How to use ChoiceField and ModelChoiceField with allauth Templates?
Based on the default allauth Templates I want to build a Custom SignUp Form which also includes ChoiceField and ModelChoiceField. Therefore I did the following adjustments:
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" %}
...
Options only get populated to attrs.value when passing 'initial' parameter in the form. Shouldn't this be provided by 'choices' or 'queryset' parameter instead? Is there an option to get the values from attrs object in a different way?
initial=…
[Django-doc] expects one element, right now you pass all, so a collection of elements, so:
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'),
)
The templates field.html and fields.html got adjusted today, so they can also handle ChoiceField and ModelChoiceField properly by passing choices parameter:
https://github.com/pennersr/django-allauth/commit/1eac57caaab22d40b1df99b272b9f34c795212cc
Than it can be used like this:
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())