Установка атрибута на основе другого атрибута

Как установить выбор общежития по половому признаку?

Глобальные переменные

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

Вернуться на верх