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 field's 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__'