Как использовать ChoiceField и ModelChoiceField с шаблонами allauth?
На основе стандартных шаблонов allauth я хочу создать пользовательскую форму регистрации, которая также включает ChoiceField и ModelChoiceField. Поэтому я сделал следующие изменения:
accounts/models.py
class Country(models.Model):
name = models.CharField(max_length=20, unique=True)
def __str__(self):
return self.name
class CustomUser(AbstractUser):
SALUTATION = (
('m', _('Mr')),
('f', _('Mrs')),
)
salutation = models.CharField(
max_length=1,
choices=SALUTATION,
blank=True,
null=True
)
country = models.ForeignKey(
Country,
on_delete=models.PROTECT,
verbose_name=_('Country'),
blank=True,
null=True
)
accounts/forms.py
class CustomSignupForm(forms.Form):
salutation = forms.ChoiceField(widget=Select, choices=CustomUser.SALUTATION, initial=CustomUser.SALUTATION)
country = forms.ModelChoiceField(queryset=Country.objects.all(), initial=Country.objects.all())
templates/allauth/elements/field.html
{% load allauth %}
{% if attrs.type == "select" %}
<select name="{{ attrs.name }}" id="{{ attrs.id }}" class="form-select mb-3">
{% for option in attrs.value %}
<option value="{% if option.0 %}{{ option.0 }}{% else %}{{ option.id }}{% endif %}">
{% if option.1 %}
{{ option.1 }}
{% else %}
{{ option }}
{% endif %}
</option>
{% endfor %}
</select>
{% elif attrs.type == "checkbox" or attrs.type == "radio" %}
...
Опции заполняются в attrs.value только при передаче параметра 'initial' в форме. Не должен ли этот параметр предоставляться параметром 'choices' или 'queryset'? Есть ли возможность получить значения из объекта attrs другим способом?
initial=…
[Django-doc] ожидает один элемент, сейчас вы передаете все, поэтому коллекция элементов, так что:
class CustomSignupForm(forms.Form):
salutation = forms.ChoiceField(
widget=Select,
choices=CustomUser.SALUTATION,
initial=CustomUser.SALUTATION,
)
country = forms.ModelChoiceField(
queryset=Country.objects.all(),
initial=Country.objects.get('United States'),
)
Сегодня были подправлены шаблоны field.html и fields.html, так что они также могут правильно обрабатывать ChoiceField и ModelChoiceField, передавая параметр choices:
https://github.com/pennersr/django-allauth/commit/1eac57caaab22d40b1df99b272b9f34c795212cc
Так что его можно использовать следующим образом:
class CustomUserCreationForm(forms.ModelForm):
salutation = forms.ChoiceField(widget=Select(attrs={'placeholder': 'Salutation'}), choices=CustomUser.SALUTATION)
country = forms.ModelChoiceField(widget=Select(attrs={'placeholder': 'Country'}), queryset=Country.objects.all())