Форум сайта python.su
0
Здравствуйте!
Надо, чтобы на форме было поле со списком пользователей (django.contrib.auth.models.User). Сделал так:
def UserList():
return tuple([(x.pk, x.last_name + ‘ ’ + x.first_name)
for x in User.objects.order_by('last_name') if x.is_active])
class NewTaskForm(forms.Form):
executor = forms.ChoiceField(choices = UserList())
Все работает, однако если добавить нового пользователя или поменять существующего, то эти изменения отразятся в форме только после перезапуска апача. В чем тут дело?
Django 0.97, mod_python, Apache 2.2
Спасибо.
Офлайн
2
johnnyскобки после UserList лишние
executor = forms.ChoiceField(choices = UserList())
Офлайн
0
Попробовал, получил исключение:
“TypeError at /addtask/0/
'function' object is not iterable”
Офлайн
2
Видимо старая джанга?
тогда так
class UserList(object): def __iter__(self): return [(x.pk, x.last_name + ' ' + x.first_name) for x in User.objects.order_by('last_name') if x.is_active]
Офлайн
0
Спасибо, завтра попробую. А не могли бы вы пояснить, почему так происходит?
Офлайн
2
Не изменяется, поскольку функция вызывается один раз при создании класса формы. Т.е. там сохраняется значение те, которые были на момент создания класса. Задача - сделать так чтобы список каждый раз был новый. Первый вариант, передать callback функцию, но у вас не работает, скорей всего из-за старой версии джанги. Второй вариант, сделать в таком случае класс (и передать в качестве choices его объект) с методом __iter__, чтобы, опять таки, каждый раз он вызывался и возвращал новый список.
Офлайн
0
Так как вы написали - выдает ошибку __iter__() возвращает не iterator.
Так работает:
class UserList(object): def __iter__(self): L = [(x.pk, x.last_name + ' ' + x.first_name) for x in User.objects.order_by('last_name') if x.is_active] return L.__iter__()
def __init__(self, attrs=None, choices=()): super(Select, self).__init__(attrs) # choices can be any iterable, but we may need to render this widget # multiple times. Thus, collapse it into a list so it can be consumed # more than once. self.choices = list(choices)
Отредактировано (Март 4, 2008 07:26:36)
Офлайн
0
поставил джангу из репозитория (ревизия 7189). Вернулся к функции, попробовал без скобок (executor = forms.ChoiceField(choices = UserList). Получил ту же ошибку: ‘function’ object is not iterable…
Попробовал руками во view-функции присваивать form.fields.choices = UserList() - все заработало…
Офлайн
0
на будущее для динамически генерируемых полей используйте вместо
class NewTaskForm(forms.Form): executor = forms.ChoiceField(choices = UserList())
class NewTaskForm(forms.Form): executor = forms.ChoiceField(choices=()) def __init__(self, data=None, *args, **kwargs): super(NewTaskForm, self).__init__(data, *args, **kwargs) self.fields['executor'].choices = UserList()
Отредактировано (Март 4, 2008 20:25:10)
Офлайн
0
Спасибо за ответы, так наверное и сделаю. Странно, что в доке на эту тему ничего не написано…
Офлайн