Установка атрибута на основе другого атрибута
Как установить выбор общежития по половому признаку?
Глобальные переменные
BOYS_HOSTEL_CHOICES = (...)
GIRLS_HOSTEL_CHOICES = (...)
class Student(models.Model):
MALE = 'M'
FEMALE = 'F'
#...
GENDER_CHOICES = (
(MALE, 'Male'),
(FEMALE, 'Female')
)
gender = models.CharField(
max_length = 10,
choices = GENDER_CHOICES,
verbose_name="gender",
)
hostel = models.CharField(
max_length=40,
choices = BOYS_HOSTEL_CHOICES if gender == 'M' # <---
else GIRLS_HOSTEL_CHOICES,
default = 'some hostel'
)
Вы не можете сделать это на уровне модели, если только вы не хотите реализовать это как ограничение базы данных. Но похоже, что вы просто хотите ограничить выбор на форме.
Разрешить оба варианта в модели:
hostel = models.CharField(
max_length=40,
# Combine choices
choices=BOYS_HOSTEL_CHOICES + GIRLS_HOSTEL_CHOICES,
default='some hostel'
)
Вы также можете использовать валидацию модели в Django для проверки ограничения на сохранение в Python.
Если вам нужно ограничить выбор в отображаемой форме, форма должна знать значение поля gender
и затем может ограничить выбор по полю hostel
.
from django import forms
class StudentForm(forms.ModelForm):
# ...
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['hostel'].choices = BOYS_HOSTEL_CHOICES
Если вы не знаете суперсета выбора хостела, то вам не следует устанавливать атрибут choices в модели, потому что модель django проверяет поле choices.
Сделать поле hostel как CharField без атрибута choices
hostel = models.CharField(max_length=40)
В этом случае можно создать форму или модельформу, в которой можно задать динамический выбор.
from django import forms
class StudentForm(forms.ModelForm):
default_choices = [your default choices if you want]
hostel = forms.CharField(max_length=40, choices = default_choices)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['hostel'].choices = self.get_dynamic_choice()
def get_dynamic_choice(self):
''' you can set choices BOYS_HOSTEL_CHOICES or GIRLS_HOSTEL_CHOICES'''
return choices
но если вы хотите, чтобы зависимый выпадающий список означал, что при выборе поля gender вы изменяете значение hostel выбора, то вы можете реализовать это с помощью javascript или Ajax call