yourlabs / django-autocomplete-light

A fresh approach to autocomplete implementations, specially for Django. Status: v4 alpha, v3 stable, v2 & v1 deprecated.
https://django-autocomplete-light.readthedocs.io
MIT License
1.8k stars 467 forks source link

Unable to get the autocomplete drop down. Normal form is presented but works #1139

Open ganeshkbhat opened 4 years ago

ganeshkbhat commented 4 years ago

The views are not showing autocomplete. This is what I have done. Using django 3.x

forms.py

from dal import autocomplete
from django import forms
from .models import Demo, Inquiry
class DemoForm(autocomplete.FutureModelForm):
    name = forms.ModelChoiceField(
        queryset=Inquiry.objects.all(),
        widget=autocomplete.ModelSelect2(url='name-autocomplete')
    )
    class Meta:
        model = Demo
        fields = ('__all__')
        widgets = {
            'name': autocomplete.ModelSelect2(url='name-autocomplete')
        }

admin.py

from django.contrib import admin
from .models import Inquiry, Demo
from .forms import DemoForm
class DemoAdmin(admin.ModelAdmin):
    form = DemoForm
    fields = (
        ('name',),
    )
class InquiryAdmin(admin.ModelAdmin):
    fields = (
        ('first_name', 'last_name'), 
    )
admin.site.register(Inquiry, InquiryAdmin)
admin.site.register(Demo, DemoAdmin)

views.py

class InquiryAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        # Don't forget to filter out results depending on the visitor !
        if not self.request.user.is_authenticated():
            return Inquiry.objects.none()
        qs = Inquiry.objects.all()
        if self.q:
            qs = qs.filter(first_name__istartswith=self.q)
        return qs

models.py

class Inquiry(models.Model):
    # first, last name
    first_name = models.CharField(verbose_name='first name', max_length=200)
    last_name = models.CharField(verbose_name='last name', max_length=200)
    class Meta:
        verbose_name = "Inquiry"
        verbose_name_plural = "Inquiries"
    def __str__(self):
        return '{} {} - {}'.format(self.first_name, self.last_name)

class Demo(models.Model):
    # first, last name
    name = models.ForeignKey(Inquiry, related_name="inquiry_name_fk", on_delete=models.PROTECT, default=None)
    class Meta:
        verbose_name = "Demo"
        verbose_name_plural = "Demos"
    def __str__(self):
        return '{} {} - {}'.format(self.name, self.date, self.trainer)

urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path(
        r'^name-autocomplete/$',
        InquiryAutocomplete.as_view(),
        name='name-autocomplete',
    ),
]
Rastopapola commented 4 years ago

Does your template include something like the following?

...
{{ form }}
{{ form.media }}
...

You have to render the form first, then rerender using the .media attribute. This was the problem for me.

jpic commented 4 years ago

Absolutely correct @Rastopapola