Использование exclude с наборами полей Django - PullRequest
4 голосов
/ 22 июля 2011

Я пытаюсь написать динамическую форму для моделей, которые позволяют пользователям с разными разрешениями делать разные вещи. Я хотел бы, чтобы приведенный ниже код функционировал должным образом, чтобы не суперпользователи не могли редактировать ни одно из полей в блоке «Торговец».

class CategoryModelAdmin(LWModelAdmin):
    fieldsets = (
        ('Merchant', {'fields': ('merchant',) }),
        ('Category', { 'fields': ('name', 'parent',) }),
    )
    def get_form(self,request,obj=None, **kwargs): 
        if request.user.is_superuser:
            self.exclude = []
        else:
            self.exclude = ['Merchant']
        return super(CategoryModelAdmin,self).get_form(request, obj=None, **kwargs)

Хотя я могу добиться этого эффекта с помощью приведенного ниже кода, я действительно ищу «правильный» способ сделать это, и мне кажется, что использование exclude - это путь, но я не могу понять, что это правильно что бы я ни пытался.

class CategoryModelAdmin(LWModelAdmin):
    declared_fieldsets = None
    admin_fieldsets = (
        (None, {'fields': ('merchant',) }),
        ('Category', { 'fields': ('name', 'parent',) }),
    )
    restricted_fieldsets = (
        ('Category', { 'fields': ('name', 'parent',) }),
    )

    def get_fieldsets(self, request, obj=None):
        if request.user.is_superuser:
            fieldsets = self.admin_fieldsets
        else:
            fieldsets = self.restricted_fieldsets
        return LWModelAdmin.fieldsets + fieldsets

    def get_form(self, request, obj=None, **kwargs):
        self.declared_fieldsets = self.get_fieldsets(request, obj)
        return super(self.__class__, self).get_form(request, obj)

Ответы [ 2 ]

3 голосов
/ 22 июля 2011

Ваш код не является потокобезопасным, вы не должны устанавливать атрибуты для себя (self.exclude и т. Д.) В ваших пользовательских методах ModelAdmin.Вместо этого используйте kwargs ModelAdmin.get_form и InlineModelAdmin.get_formset, чтобы получить то, что вы хотите.

Вот простой пример:

class CategoryModelAdmin(LWModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            kwargs['exclude'] = ['foo', 'bar',]
        else:
            kwargs['fields'] = ['foo',]
        return super(CategoryModelAdmin, self).get_form(request, obj, **kwargs)
1 голос
/ 22 июля 2011

Я не уверен, если это будет более или менее взломать, но вы рассматривали это?

Создание двух разных моделей, указывающих на одну и ту же таблицу. Каждая модель может иметь свой собственный класс ModelAdmin с любыми настройками, которые вы хотите. Затем используйте разрешения Django, чтобы сделать одно из них невидимым для не являющиеся администраторами.

Если вы хотите избежать дублирования кода, вы можете получить оба ваших классы из некоторого общего базового класса, который вы создаете.

Преимущество в том, что вы не будете делать ничего, кроме того, что написано в документации. Я не думаю, что мы должны переписывать такие методы, как get_form и get_fieldsets. Если они на самом деле не являются частью опубликованного API, эти методы могут измениться или быть удалены через день, и вы можете стать владельцем обновления.

Просто мысль ...

...