динамические манипуляции с админкой django - PullRequest
1 голос
/ 24 января 2012

У меня есть измененная административная форма, в которую я добавил поле, которое будет изменять значения родительского объекта текущей модели.Теперь, в зависимости от пользователя, мне нужно

  • изменить набор запросов этого дополнительного поля
  • установить другое поле как доступное только для чтения (или лучше даже полностью его скрыть)

В основном мой код ниже работает так, как я ожидал.Суперпользователь получает весь набор запросов, а другое поле не только для чтения.Все остальные пользователи получают ограниченный набор запросов, а другое поле является только для чтения.Однако, как только я открываю этот сайт в другом браузере и, не являясь суперпользователем, даже суперпользователь получает тот же результат, что и не суперпользователь.Похоже, Django как-то кеширует результат?Если я помещу некоторые операторы print в условные ветви, они будут напечатаны правильно.Таким образом, метод по-прежнему вызывается каждый раз и, кажется, все еще выполняет эти шаги.Только с неверным результатом.

Это проблема кеширования?Я делаю что-то совершенно не так?Может ли это быть ошибкой на тестовом сервере django?

def get_form(self, request, obj=None, **kwargs):
    form = super(MultishopProductAdmin, self).get_form(request, obj, **kwargs)
    if obj is not None:
        form.declared_fields['categories'].initial = obj.product.category.all()
    if not request.user.is_superuser:
        user_site = request.user.get_profile().site
        form.declared_fields['categories'].queryset = Category.objects.filter(site__id=user_site.id)
        self.readonly_fields = ('virtual_sites', )
        if obj is not None:
            form.declared_fields['categories'].initial = obj.product.category.filter(site__id=user_site.id)
    return form

Ответы [ 3 ]

1 голос
/ 24 января 2012

Чтобы развернуть ответ anan-dlass: никогда не устанавливайте атрибуты экземпляра в каком-либо методе ModelAdmin (например, self.readonly_fields), чтобы предотвратить проблемы, подобные описанному вами.Используйте только параметры Django ModelAdmin (уровня класса) или методы для манипулирования любым поведением.Что касается полей только для чтения, вы можете использовать метод ModelAdmin.get_readonly_fields, который имеет такую ​​подпись: get_readonly_fields(self, request, obj=None).

1 голос
/ 24 января 2012

Да, вы делаете это неправильно. В Django 1.2+ вы можете использовать get_readonly_fields .

С этот ответ :

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

Относительно изменения набора запросов . Из документации:

class MyModelAdmin(admin.ModelAdmin):
    def queryset(self, request):
        qs = super(MyModelAdmin, self).queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(author=request.user)
0 голосов
/ 30 января 2012

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

Затем я предоставил пользовательский шаблон, установив change_form_template, который просто расширяет admin/change_form.html, но отображает мою собственную форму вместо формы по умолчанию. Я также установил extra_context['adminform'] = None, чтобы удалить форму администратора по умолчанию.

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

...