I have a model with a location field that is mapped to cities_light.city and I'm using an autocomplete field that allows users to type in their city and have it autocompleted to the correct/valid location model instance.
class Profile(models.Model):
location = models.ForeignKey(City, blank=True, null=True)
class ProfileForm(ModelForm):
class Meta:
model = Profile
fields = ('location')
widgets = {
'location': autocomplete_light.TextWidget(CityAutocomplete, autocomplete_js_attributes={'placeholder':'City, Country', 'minimum_characters':4})
}
The form field works exactly as advertised and a list of autocomplete options are shown. However when I save the form/model I get a validation error which seems to be caused by the field not being translated into the primary key of the City model instance.
Select a valid choice. That choice is not one of the available choices.
I'm guessing I need to extend the AutocompleteModelBase like the CityAutocomplete implemented below but I'm not sure how and I've been unable to find a working example.
class CityAutocomplete(autocomplete_light.AutocompleteModelBase):
search_fields = ('search_names',)
https://github.com/yourlabs/django-cities-light/blob/master/cities_light/contrib/autocompletes.py
Thank for any assistance and I'm sorry if my question is poorly formatted.
Your problem is not specific to django-autocomplete-light. What you're doing has no chance to work and here's why:
ForeignKey
like location
is a ModelChoiceField by default,ModelChoiceField
accepts values which are pks of models in ModelChoiceField.queryset
, which is TheModel.objects.all()
by default,TextWidget
widget is a TextInput
,TextInput
widget is just an <input type="text" />
,<input type="text" />
is directly sent to the server on form submission.As a result, selecting a couple of cities like "Lisboa" and "Madrid" with a text widget will look like::
<input type="text" value="Lisboa, Madrid" name="location" />
Which means that the form will post {'location': 'Lisboa, Madrid'}
. While this is good for a CharField
, it won't work for a ModelMultipleChoiceField
which would expect something like {'location': [3,5]}
where 3 would be the pk of Lisboa and 5 the pk of Madrid.
In the same fashion, a ModelChoiceField
would expect {'location': 3}
which autocomplete_light.ChoiceWidget
is able to do.
To fix this, use a ChoiceWidget
instead of a TextWidget
. I have clarified this in the tutorial I hope it is better now.