Найти - Пользователи
Полная версия: Не обновляется список пользователей на форме
Начало » Django » Не обновляется список пользователей на форме
1 2
johnny
Здравствуйте!
Надо, чтобы на форме было поле со списком пользователей (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
executor = forms.ChoiceField(choices = UserList())
скобки после UserList лишние
johnny
Попробовал, получил исключение:
“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]
johnny
Спасибо, завтра попробую. А не могли бы вы пояснить, почему так происходит?
Александр Кошелев
Не изменяется, поскольку функция вызывается один раз при создании класса формы. Т.е. там сохраняется значение те, которые были на момент создания класса. Задача - сделать так чтобы список каждый раз был новый. Первый вариант, передать callback функцию, но у вас не работает, скорей всего из-за старой версии джанги. Второй вариант, сделать в таком случае класс (и передать в качестве choices его объект) с методом __iter__, чтобы, опять таки, каждый раз он вызывался и возвращал новый список.
johnny
Так как вы написали - выдает ошибку __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__()
Однако желаемого эффекта это не дало. В конструкторе виджета Select
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)
насколько я понял, все приводится к списку.
Судя по вашим постам, я использую не последнюю джангу. Счас попробую поставить последнюю ревизию из их репозитория.

Мне непонятно вот что: форма-то создается каждый раз при вызове view. Соответственно, создается и этот виджет. Почему же при этом не дергается моя функция (ваш класс)?
johnny
поставил джангу из репозитория (ревизия 7189). Вернулся к функции, попробовал без скобок (executor = forms.ChoiceField(choices = UserList). Получил ту же ошибку: ‘function’ object is not iterable…
Попробовал руками во view-функции присваивать form.fields.choices = UserList() - все заработало…
playpauseandstop
на будущее для динамически генерируемых полей используйте вместо
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()
иначе говоря,не засоряйте логику вьюсов разнообразными манипуляциями с формой (моделями, классами и тд, и тп)
johnny
Спасибо за ответы, так наверное и сделаю. Странно, что в доке на эту тему ничего не написано…
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB