Ограничение выбора поля выбора в классе модели
Этот ответ SO показывает, как ограничить поле выбора в форме. Однако у меня есть поле выбора с вариантами, которые никогда не должны быть показаны пользователю. Следовательно, я хочу ограничить опции поля выбора в классе модели, чтобы придерживаться принципа DRY и не дать себе забыть добавить код в будущие формы.
Вот простой пример:
UNIT_TYPES = Choices(
(1, 'APARTMENT', 'Apartment'),
(2, 'TOWNHOUSE', 'Townhouse'),
(3, 'SINGLE_FAMILY', 'Single-family home'),
(4, 'OTHER', 'Other') # Never show in any views
)
В данном конкретном примере только первые три варианта должны быть показаны пользователю в формах, тогда как четвертый будет установлен на бэкенде только при выполнении определенных условий.
Есть идеи, как этого добиться?
Я бы создал другой набор вариантов в вашем файле models.py для тех, которые скрыты, например
UNIT_TYPES = Choices(
(1, 'APARTMENT', 'Apartment'),
(2, 'TOWNHOUSE', 'Townhouse'),
(3, 'SINGLE_FAMILY', 'Single-family home'),
)
HIDDEN_TYPES = Choices(
(4, 'OTHER', 'Other') # Never show in any views
)
Вы должны иметь возможность установить выбор модели как UNIT_TYPES + HIDDEN_TYPES
и затем получить доступ к HIDDEN_TYPES
в файле формы. Ссылаясь на ответ, на который вы ссылались, вы можете настроить функцию __init__()
, чтобы установить варианты выбора на основе UNIT_TYPES
и полностью игнорировать HIDDEN_TYPES
.
Если в вашем приложении есть другие места, где пользователь может увидеть эти варианты, то вам нужно позаботиться о том, чтобы исключить скрытые типы. Насколько я знаю, нет способа сделать это более динамичным - метод модели __init__()
не имеет доступа к объекту request
, который сообщил бы вам, какой пользователь задействован.
Использование пользовательского менеджера, который всегда будет исключать один из ваших вариантов :
APARTMENT = 1
TOWNHOUSE = 2
SINGLE_FAMILY = 3
OTHER = 4
UNIT_TYPES = (
(APARTMENT, 'Apartment'),
(TOWNHOUSE, 'Townhouse'),
(SINGLE_FAMILY, 'Single-family home'),
(OTHER, 'Other')
)
class CustomManager(models.Manager):
def get_queryset(self):
return super().get_queryset().exclude(unit_type=OTHER)
class Model(models.Model):
unit_type = models.IntegerField(
choices=UNIT_TYPES,
validators=[MinValueValidator(APARTMENT), MaxValueValidator(OTHER)]
)
objects = CustomManager()