Как отфильтровать набор запросов в changelist_view в django admin? - PullRequest
6 голосов
/ 12 апреля 2010

Допустим, у меня есть сайт, где пользователи могут добавлять записи через админ-панель. У каждого пользователя есть своя собственная категория, за которую он отвечает (для каждой категории есть редактор, назначенный через ForeingKey / ManyToManyField).

Когда пользователь добавляет запись, я ограничиваю выбор с помощью EntryAdmin следующим образом:

class EntryAdmin(admin.ModelAdmin):
    (...)

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'category':
            if request.user.is_superuser:
                kwargs['queryset'] = Category.objects.all()
            else:
                kwargs['queryset'] = Category.objects.filter(editors=request.user)
            return db_field.formfield(**kwargs)
        return super(EntryAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

Таким образом, я могу ограничить категории, к которым пользователь может добавить запись, и это прекрасно работает.

Теперь сложная часть: на странице списка изменений / действий в Entry я хочу показать только те записи, которые принадлежат к категории текущего пользователя. Я пытался сделать это, используя этот метод:

    def changelist_view(self, request, extra_context=None):
        if not request.user.is_superuser:
            self.queryset = self.queryset.filter(editors=request.user)

Но я получаю эту ошибку:

AttributeError: у объекта 'function' нет атрибута 'filter'

Это странно, потому что я подумал, что это должен быть типичный QuerySet. В основном такие методы плохо документированы , и копаться в тоннах кода Django - не мой любимый вид спорта.

Есть идеи, как мне достичь своей цели?

1 Ответ

14 голосов
/ 12 апреля 2010

queryset - это метод ModelAdmin, который возвращает набор запросов. Вам нужно переопределить его в вашем EntryAdmin классе.

def queryset(self, request):
    qs = super(EntryAdmin, self).queryset(request)
    if request.user.is_superuser:
        return qs
    else:
        return qs.filter(editors=request.user)

Изменение набора запросов ограничит количество записей, отображаемых в виде списка. Вам также необходимо переопределить has_change_permission, чтобы убедиться, что у пользователя есть разрешение на редактирование объекта на странице редактирования отдельного объекта. См. Следующее сообщение в блоге Джеймса Беннетта для получения дополнительной информации:

http://www.b -list.org / блог / 2008 / Декабрь / 24 / админ /

...