@nurzhannogerbek

Формирование queryset-ов для кастомных полей в Джанго?

Здравствуйте! Помогите пожалуйста разобраться.

Есть два кастомных поля: current_permissions и available_permissions в форме. Вы можете увидеть их на картинке снизу. При GET запросе в правом списке хочу выводить права конкретного пользователя, в левом списке выводить доступные права пользователей, которые еще не выбраны. В админке Джанго для редактирования прав пользователей уже существует подобный виджет, возможно можно его вынести из админки?

Использал следующий код, но он выводит ошибку. Список текущих прав пользователя формируется во вьюшке. Возможно из view не правильно переношу параметр current_permissions в forms. Далее уже на основе current_permissions формировал queryset-ы для полей. Где моя ошибка?

P.S. Использую Питон 2.7.

forms.py:
class UserEditForm(UserChangeForm):
    available_permissions = forms.ModelMultipleChoiceField(
        widget=forms.SelectMultiple,
        required=False,
        queryset=None,
    )

    current_permissions = forms.ModelMultipleChoiceField(
        widget=forms.SelectMultiple,
        required=False,
        queryset=None,
    )

    def __init__(self,  *args, **kwargs):
        self.current_permissions = kwargs.pop('current_permissions')
        super(UserEditForm, self).__init__(*args, **kwargs)
        if current_permissions:
            self.fields['current_permissions'].queryset = self.current_permissions
            final_available_permissions = list()
            for available_permission in Permission.objects.all():
                if available_permission not in self.current_permissions:
                    final_available_permissions.append(available_permission)
            none_qs = Permission.objects.none()
            qs = list(chain(none_qs, final_available_permissions))
            self.fields['available_permissions'].queryset = qs


views.py:
class UserEditView(UpdateView):
    template_name = 'users/edit_user.html'
    form_class = UserEditForm
    model = User

    def get(self, request, *args, **kwargs):
        user = User.objects.get(pk=self.kwargs['pk'])
        context = {
            'user': user,
            'user_edit_form': UserEditForm(
                instance=user,
                current_permissions=user.get_all_permissions()
            ),
        }


ERROR:
Traceback (most recent call last):
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/views/generic/base.py", line 88, in dispatch
    return handler(request, *args, **kwargs)
  File "/Applications/Projects/web/dashboard.kase.kz/users/views.py", line 69, in get
    data['html_form'] = render_to_string('users/edit_user.html', context, request=request)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/template/loader.py", line 68, in render_to_string
    return template.render(context, request)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/template/backends/django.py", line 66, in render
    return self.template.render(context)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/template/base.py", line 207, in render
    return self._render(context)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/template/base.py", line 199, in _render
    return self.nodelist.render(context)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/template/defaulttags.py", line 173, in render
    len_values = len(values)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/forms/boundfield.py", line 71, in __len__
    return len(self.subwidgets)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/utils/functional.py", line 35, in __get__
    res = instance.__dict__[self.name] = self.func(instance)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/forms/boundfield.py", line 57, in subwidgets
    for widget in self.field.widget.subwidgets(self.html_name, self.value(), attrs=attrs)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/forms/boundfield.py", line 56, in <genexpr>
    BoundWidget(self.field.widget, widget, self.form.renderer)
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/forms/widgets.py", line 561, in subwidgets
    for option in self.options(name, value, attrs):
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/forms/widgets.py", line 566, in options
    for group in self.optgroups(name, value, attrs):
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/forms/widgets.py", line 575, in optgroups
    for index, (option_value, option_label) in enumerate(chain(self.choices)):
  File "/Users/nurzhan_nogerbek/Virtualenvs/py2714/lib/python2.7/site-packages/django/forms/models.py", line 1135, in __iter__
    queryset = self.queryset.all()
AttributeError: 'list' object has no attribute 'all'


5a14071578415408543406.png
  • Вопрос задан
  • 662 просмотра
Решения вопроса 1
Что-то вы в целом с формой перемудрили похоже :)

Достаточно одного поля user_permissions. При рендере формы сформируется корректный html селект, с отмеченными существующими правами. Все что останется - навесить какой нибудь js плагин по вкусу, который поддерживает мультиселекты (select2 тот же, например).

Если хочется конкретно из админки, то гуглится довольно просто www.hoboes.com/Mimsy/hacks/replicating-djangos-adm...
Хотя как по мне это несколько неудобно.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы