Django how do you AutoComplete a ForeignKey Input field using Crispy Forms

318 views Asked by At

Looking for any assistance as i just can't seem to get this. I have a 'category' field that has approx 4000 categories in it, sourced from my table "Category". When a user inputs their details they choose from the category field. This works fine as a drop down list but takes ages to scroll. I'd rather have the field as text entry so when they start typing, for example 'plum', then every category with 'plum' somewhere in it appears in the list so they can choose. They must also choose from list and not enter rubbish. Can anyone assist?

Here's how it works just now with the drop down list, is there any way to change this (category1) to an autocomplete field? I've looked at django autocomplete_light but got nowhere.

Models.py:

class Category(models.Model):
    details = models.CharField(max_length=250, blank=True, null=True)

    def __str__(self):
        return self.details

class Search(models.Model):
    name = models.CharField(max_length=200)
    email = models.CharField(max_length=200)
    category1 = models.ForeignKey('Category', blank=True, null=True, on_delete=models.CASCADE, related_name='category')

Forms.py:

class NewSearch(forms.ModelForm):
    class Meta:
        model = Search
        fields = ['name', 'email', 'category1']

    def __init__(self, *args, **kwargs):
        super(NewSearch, self).__init__(*args, **kwargs)
        self.fields['category1'] = forms.ModelChoiceField(queryset=Category.objects.all().order_by('details'))
        self.helper = FormHelper()
        self.helper.form_show_labels = False

Views.py:

@csrf_exempt
def search(request):
    my_form = NewSearch()
    if request.method == 'POST':
        my_form = NewSearch(request.POST)
        if my_form.is_valid():
            my_form.save()
            return redirect('frontpage-results')
    context = {
        'my_form': my_form,
    }
    return render(request, 'frontpage/search.html', context)

Search.html:

<form method="POST" class="page-section" enctype="multipart/form-data">
    <div>
        {% csrf_token %}
        <fieldset class="form-group">
             <div class="form-row">
                <div class="form-group col-md-5 mb=0">
                    Your Full Name:
                    {{ my_form.name|as_crispy_field }}
                </div>
                <div class="form-group col-md-7 mb=0">
                    Your E-mail Address:
                    {{ my_form.email|as_crispy_field }}
                </div>
                <div class="form-group col-md-4 mb=0">
                    Category you are looking for:
                    {{ my_form.category1|as_crispy_field }}
                </div>
             </div>
             {{ my_form.media }}        {# Form required JS and CSS #}
        </fieldset>
        <div class="form-group">
            <button class="btn btn-secondary" type="submit" name="first">SEARCH NOW</button>
        </div>
   </div>
</form>

Urls.py:

urlpatterns = [
    path('', views.home, name='frontpage-home'),
    path('search/', views.search, name='frontpage-search'),
]

MY SOLUTION (but this didn't work):

SETTINGS.PY

INSTALLED_APPS = [
    'autocomplete_light',

URLS.PY (added this line)

path('autocomplete/', include('autocomplete_light.urls')),

FORMS.PY

import autocomplete_light

autocomplete_light.register(Search, name='CatAutocomplete', choices=Category.objects.all())

class NewSearch(forms.ModelForm):
    class Meta:
        model = Search
        fields = ['name', 'email', 'category1']
        autocomplete_fields = {'category1': 'CatAutocomplete'}

    def __init__(self, *args, **kwargs):
        super(NewSearch, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_show_labels = False

But i got the error AttributeError: module 'autocomplete_light' has no attribute 'register'" and got no further, any ideas? Thanks

1

There are 1 answers

0
Daniel Hepper On

Try changing your import:

import autocomplete_light.shortcuts as al

al.register

This has changed in version 2.2:

2.2.0rc1

    PENDING BREAK WARNING, Django >= 1.9.

    The good old ``import autocomplete_light`` API support will be dropped with
    Django 1.9. All imports have moved to ``autocomplete_light.shortcuts`` and
    importing ``autocomplete_light`` will work until the project is used with
    Django 1.9.

Apparently, the documentation wasn't properly updated.