Установка self.exclude
делает так, как упоминает @ steve-pike, заставить целое SubSectionAdmin
singleton изменить свое свойство exclude.
Singleton - это класс, который будет повторно использовать один и тот же экземпляр каждый раз, когда создается экземпляр класса, поэтому экземпляр создается только при первом использовании конструктора, а последующее использование конструктора возвращает тот же экземпляр. Смотрите вики-страницу для более подробного описания.
Это означает, что если вы напишите код для исключения поля при изменении, это будет означать, что если вы впервые добавите элемент, поле будет там, но если вы откроете элемент для изменения, поле будет исключено для следующих посещений. на страницу добавления.
Простейший способ добиться поведения для каждого запроса - использовать get_fields
и проверить аргумент obj
, который равен None
, если мы добавляем объект, и экземпляр объекта, если мы меняемся. объект. Метод get_fields
доступен в Django 1.7.
class SubSectionAdmin(admin.ModelAdmin):
def get_fields(self, request, obj=None):
fields = super(SubSectionAdmin, self).get_fields(request, obj)
if obj: # obj will be None on the add page, and something on change pages
fields.remove('field')
return fields
Обновление:
Обратите внимание, что get_fields
может возвращать кортеж, поэтому вам может потребоваться преобразовать fields
в список для удаления элементов.
Вы также можете столкнуться с ошибкой, если имя поля, которое вы пытаетесь удалить, отсутствует в списке. Поэтому в некоторых случаях, когда у вас есть другие факторы, исключающие поля, может быть лучше создать набор исключений и удалить их, используя понимание списка:
class SubSectionAdmin(admin.ModelAdmin):
def get_fields(self, request, obj=None):
fields = list(super(SubSectionAdmin, self).get_fields(request, obj))
exclude_set = set()
if obj: # obj will be None on the add page, and something on change pages
exclude_set.add('field')
return [f for f in fields if f not in exclude_set]
В качестве альтернативы вы также можете получить deepcopy
результата в методе get_fieldsets
, который в других случаях может дать вам доступ к лучшему контексту для исключения вещей. Очевидно, это будет полезно, если вам нужно действовать с именем набора полей. Кроме того, это единственный путь, если вы действительно используете fieldsets , так как при этом вызов на get_fields
.
будет опущен.
from copy import deepcopy
class SubSectionAdmin(admin.ModelAdmin):
def get_fieldsets(self, request, obj=None):
"""Custom override to exclude fields"""
fieldsets = deepcopy(super(SubSectionAdmin, self).get_fieldsets(request, obj))
# Append excludes here instead of using self.exclude.
# When fieldsets are defined for the user admin, so self.exclude is ignored.
exclude = ()
if not request.user.is_superuser:
exclude += ('accepted_error_margin_alert', 'accepted_error_margin_warning')
# Iterate fieldsets
for fieldset in fieldsets:
fieldset_fields = fieldset[1]['fields']
# Remove excluded fields from the fieldset
for exclude_field in exclude:
if exclude_field in fieldset_fields:
fieldset_fields = tuple(field for field in fieldset_fields if field != exclude_field) # Filter
fieldset[1]['fields'] = fieldset_fields # Store new tuple
return fieldsets