Django Modelforms: how to show a select for a CharField?

Django Modelforms: how to show a select for a CharField?

If you would like to fix this attribute error you can either pass your choices as a python Tuple or set TypedChoiceField() and give it the attribute coerce reference this: https://stackoverflow.com/a/18200849/14127147

from django import forms
CHOICES = ((1, First), (2, Second))
choice_field = forms.ChoiceField(widget=forms.Select, choices=CHOICES)
form.fields[street].widget = choice_field

The preferred way to use ModelForm is to create own class:

class StreetForm(forms.ModelForm):
    class Meta:
        model = Street
        fields = __all__

This would create a form for editing Street attributes like name.

If you want to create a form with streets to select, and you should define a new form – an another ModelForm if Street is in a relation to the other model (i.e. defined by ForeignKey), or a plain Form otherwise.

Assuming the second scenario you should define:


class OtherForm(forms.Form):
    street = forms.ModelChoiceField(queryset=Street.objects.all())

To narrow streets you have two choices, depending on the filtering criteria.

For static filtering (where criteria would not change at runtime) you can narrow records by defining a filtered queryset:


class OtherForm(forms.Form):
    street = forms.ModelChoiceField(
        queryset=Street.objects.filter(name__ilike=a%)
    )

For dynamic filtering you may override a fields queryset instance in __init__ method:

class OtherForm(forms.Form):
    street = forms.ModelChoiceField(
        queryset=Street.objects.all()
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)  # must be called first
        self.fields[street].queryset = Street.objects.filter(...)

The default widget for ModelChoiceField is a Select widget.

But if you need to prepare custom choices for street names, you should define a choices list (as in your example) and redefine a name field of the StreetForm:


STREET_NAME_CHOICES = [
   (Street name 1, Street name 1), 
   (Street name 2, Street name 2)
]

class StreetForm(forms.ModelForm):
    name = forms.ChoiceField(
        widget=forms.Select,
        choices=STREET_NAME_CHOICES
    )
    class Meta:
        model = Street
        fields = __all__

Django Modelforms: how to show a select for a CharField?

Leave a Reply

Your email address will not be published.