Question

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.

Was it helpful?

Solution

Your problem is not specific to django-autocomplete-light. What you're doing has no chance to work and here's why:

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top