Search code examples
pythondjangopython-3.xautocompletedjango-autocomplete-light

Django Autocomplete Light List Object has no Attribute Queryset


Please look at my edits at the end of my code as well.

I'm attempting to implement django-autocomplete-light (dal 3.2.10) for a single field. Following the tutorial, I turn up this error: 'list' object has no attribute 'queryset'.

I have seen this question: django-autocomplete-light error = 'list' object has no attribute 'queryset'. It did not resolve my issue.

Why is this error occurring? What can I do to combat this?

I don't think this is the entire problem, but I don't see any js files show up in the browser inspector. I thought including the code in Edit #3 would cause something to show up.

I have two models:

class Entity(models.Model):
    entity = models.CharField(primary_key=True, max_length=12)
    entityDescription = models.CharField(max_length=200)
    def __str__(self):
        return self.entityDescription

class Action(models.Model):
    entity = models.ForeignKey(Entity, on_delete=models.CASCADE, db_column='entity')
    entityDescription = models.CharField(max_length=200)
    action = models.CharField(max_length=50)
    def __str__(self):
        return '%s' % self.entity

I have a model form and formset. I am also using crispy-forms to render the formset:

class ActionForm(ModelForm):
class Meta:
    model = Action
    fields = '__all__'
    widgets = {
        'entityDescription': autocomplete.ModelSelect2(url='eda')
    }

ActionFormSet = modelformset_factory(Action, extra=1, exclude=(), form=ActionForm)

I have a view:

class EntityDescriptionAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
    qs = Entity.objects.all()
    if self.q:
        qs = qs.filter(entityDescription__istartswith=self.q)
    return qs

I have a urls.py:

urlpatterns = [
    url(
        r'^eda/$',
        views.EntityDescriptionAutocomplete.as_view(),
        name='eda',
    ),
]

Thank you for any insight you all might have.

Edit:

I changed...

widgets = {
        'entityDescription': autocomplete.ModelSelect2(url='eda'),
}

...to...

widgets = {
        'entityDescription': autocomplete.Select2(url='eda'),
}

...this allowed my page to render, but the autocomplete field is an empty dropdown. Why is it empty, and why is it not an autocomplete box?

Edit #2:

I removed the widget setting in the meta class and instead overrode the field directly:

class ActionForm(ModelForm):
    entityDescription = ModelChoiceField(
        queryset=Entity.objects.all(),
        widget=autocomplete.ModelSelect2(url='eda')
        )
    class Meta:
        model = Action
        fields = '__all__'

This still returns an empty dropdown (not an autocomplete box), but it now has Django's ------- signifier instead of absolutely nothing.

Edit #3:

I added this to my template:

{% block footer %}
<script type="text/javascript" src="/static/collected/admin/js/vendor/jquery/jquery.js"></script>
{{ form.media }}
{% endblock %}

Nothing changed.


Solution

  • Your ActionForm, and EntityDescriptionAutocomplete look fine.

    Is your autocomplete view returning results?

    You should be able to browse to the autocomplete view's URL (in your case /eda) and see JSON results from the query. Is the set non-empty?

    {"pagination": {"more": true}, "results": [{"text": "foo", "id": "1" ...
                                               ^^^^^^^^^^^^^^^^^^^^^^^^
    

    Does your rendered HTML include the libraries?

    You should see the following in your HTML source, where you put the {{ form.media }} tag:

    <link href="/static/autocomplete_light/vendor/select2/dist/css/select2.css" type="text/css" media="all" rel="stylesheet" />
    <link href="/static/autocomplete_light/select2.css" type="text/css" media="all" rel="stylesheet" />
    <script type="text/javascript" src="/static/autocomplete_light/jquery.init.js"></script>
    <script type="text/javascript" src="/static/autocomplete_light/autocomplete.init.js"></script>
    <script type="text/javascript" src="/static/autocomplete_light/vendor/select2/dist/js/select2.full.js"></script>
    <script type="text/javascript" src="/static/autocomplete_light/select2.js"></script>
    

    If not,

    Are you referring to the correct form variable?

    The form in {{ form.media }} should refer to whatever name you have given to your form in the context being passed to your page template.