Дополнительно¶
Цепочечный select2¶
Предположим, у вас есть адресная форма, где пользователь должен выбрать страну и город. Когда пользователь выбирает страну, мы хотим показывать только города, принадлежащие этой стране. Таким образом, один селектор зависит от другого.
Модели¶
Вот наши две модели:
class Country(models.Model):
name = models.CharField(max_length=255)
class City(models.Model):
name = models.CharField(max_length=255)
country = models.ForeignKey('Country', related_name="cities")
Настройка формы¶
Давайте свяжем два виджета через зависимые поля.
class AddressForm(forms.Form):
country = forms.ModelChoiceField(
queryset=Country.objects.all(),
label=u"Country",
widget=ModelSelect2Widget(
model=Country,
search_fields=['name__icontains'],
)
)
city = forms.ModelChoiceField(
queryset=City.objects.all(),
label=u"City",
widget=ModelSelect2Widget(
model=City,
search_fields=['name__icontains'],
dependent_fields={'country': 'country'},
max_results=500,
)
)
Взаимозависимый select2¶
Также вы можете не ограничивать пользователя тем, какое поле следует выбрать первым. Вместо этого вы хотите предложить пользователю варианты для любого select2 в зависимости от его выбора в другом.
Настройте форму таким образом:
class AddressForm(forms.Form):
country = forms.ModelChoiceField(
queryset=Country.objects.all(),
label=u"Country",
widget=ModelSelect2Widget(
search_fields=['name__icontains'],
dependent_fields={'city': 'cities'},
)
)
city = forms.ModelChoiceField(
queryset=City.objects.all(),
label=u"City",
widget=ModelSelect2Widget(
search_fields=['name__icontains'],
dependent_fields={'country': 'country'},
max_results=500,
)
)
Обратите внимание на зависимые поля страны. Значение „city“ равно „cities“ из-за связанного имени, использованного в условии фильтра cities, которое отличается от имени поля виджета` city`.
Осторожно
Помните об использовании взаимозависимого select2 в родительско-дочерних отношениях. Когда ребенок выбран, вы можете сменить родителя (доступно только одно значение). Вероятно, вы должны позволить пользователю сбросить дочерний элемент первым, чтобы освободить родительский select2.
Мульти-зависимый select2¶
Кроме того, вы можете захотеть отфильтровать опции для двух или более выборов select2 (для ясности часть кода пропущена):
class SomeForm(forms.Form):
field1 = forms.ModelChoiceField(
widget=ModelSelect2Widget(
)
)
field2 = forms.ModelChoiceField(
widget=ModelSelect2Widget(
)
)
field3 = forms.ModelChoiceField(
widget=ModelSelect2Widget(
dependent_fields={'field1': 'field1', 'field2': 'field2'},
)
)