Форум сайта python.su
Здравствуйте!
Надо, чтобы на форме было поле со списком пользователей (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
Спасибо.
Офлайн
johnnyскобки после UserList лишние
executor = forms.ChoiceField(choices = UserList())
Офлайн
Попробовал, получил исключение:
“TypeError at /addtask/0/
'function' object is not iterable”
Офлайн
Видимо старая джанга?
тогда так
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]
Офлайн
Спасибо, завтра попробую. А не могли бы вы пояснить, почему так происходит?
Офлайн
Не изменяется, поскольку функция вызывается один раз при создании класса формы. Т.е. там сохраняется значение те, которые были на момент создания класса. Задача - сделать так чтобы список каждый раз был новый. Первый вариант, передать callback функцию, но у вас не работает, скорей всего из-за старой версии джанги. Второй вариант, сделать в таком случае класс (и передать в качестве choices его объект) с методом __iter__, чтобы, опять таки, каждый раз он вызывался и возвращал новый список.
Офлайн
Так как вы написали - выдает ошибку __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)
Офлайн
поставил джангу из репозитория (ревизия 7189). Вернулся к функции, попробовал без скобок (executor = forms.ChoiceField(choices = UserList). Получил ту же ошибку: ‘function’ object is not iterable…
Попробовал руками во view-функции присваивать form.fields.choices = UserList() - все заработало…
Офлайн
на будущее для динамически генерируемых полей используйте вместо
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)
Офлайн
Спасибо за ответы, так наверное и сделаю. Странно, что в доке на эту тему ничего не написано…
Офлайн