4

I've been doing website using Django lately and I encountered difficulties in implementing chained drop-down / dependent drop-down. I tried smart-selects but couldn't implement it, that's when I stumbled with django-autocomplete-light.

I was able to implement this and it fits my current requirement, however, I have noticed that python is throwing this warning:

UnorderedObjectListWarning: Pagination may yield inconsistent results
with an unordered object_list: <class 'project.models.Driver'> QuerySet.

I followed tutorial from the django-autocomplete-light thoroughly and I'm still missing something.

forms.py

class TripModelForm(forms.ModelForm):

    driver = forms.ModelChoiceField(
        queryset=Driver.objects.all(),
        widget=autocomplete.ModelSelect2(url='driver_autocomplete',
                                         forward=['hauler'])
    )

    class Meta:
        model = Trip
        fields = ['ticket', 'date_issued', 'department', 'hauler', 'plate_number', 'driver',]

urls.py

urlpatterns += [
    path('driver-autocomplete/', views.DriverAutocomplete.as_view(), name='driver_autocomplete'),
]

views.py

class DriverAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):

        if not self.request.user.is_authenticated():
            return Driver.objects.none()

        qs = Driver.objects.all()
        hauler = self.forwarded.get('hauler', None)

        if hauler:
            qs = qs.filter(hauler=hauler)
        if self.q:
            qs = qs.filter(name__istartswith=self.q)

        return qs
Josh21
  • 506
  • 5
  • 15

1 Answers1

6

I followed where the error come from which is in \python36\lib\site-packages\django\views\generic\list.py:88. It looks like the class expects ordered queryset so I have modified the views.py to this:

views.py

class DriverAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):

        if not self.request.user.is_authenticated():
        return Driver.objects.none()

        qs = Driver.objects.all().order_by('name') <-- here
        if self.q:
        hauler = self.forwarded.get('hauler', None)

        if hauler:
            qs = qs.filter(hauler=hauler)
        if self.q:
            qs = qs.filter(name__istartswith=self.q)

        return qs

This solution worked for me and I was able to duplicate the warning by removing the .order_by in the query.

Josh21
  • 506
  • 5
  • 15