Django-autocomplete-light: Using of django-autocomplete-light with CharField (not as tags)

Created on 4 Aug 2019  Â·  9Comments  Â·  Source: yourlabs/django-autocomplete-light

Hi! Thank you for cool lib! But I can't find, how I can use your lib as I wish.

I have model like this

class Company(Model):
    name = CharField(max_length=128, unique=True)

This is companies, with wich our company works. As you see, company must be unique for our tasks.

We plan to have some managers, and each of them can add the same company with other name. One guy can add 'Google' and other guy add 'Google.com'. And other managers can create orders or any other operations with both of this objecs. It is a problem...

I think, that the best way to resolve this problem is using of autocomplete, when manager is typing name of company, wich he wants to add.

Functionality of TagSelect2 widget looks like something suitable for me. But after I choose inputed text, I look tag, after wich I can add some more tags.
изображение

I don't want to create tags, I only want to use autocomplete as helpers, when typing text and to have on output something like this:
изображение

Can I do it with your lib?

Most helpful comment

It's a pity. Would be nice if it will be in-box feature.

All 9 comments

I don't think so, unless you implement your own replacement for select2

It's a pity. Would be nice if it will be in-box feature.

Are any recomendations, how can I do it manualy?

I am having the very same need.

I almost got it working with the aid of a slightly tweaked Select2ListView https://django-autocomplete-light.readthedocs.io/en/master/tutorial.html#autocompleting-based-on-a-list-of-strings But after a model change the widget won't show the previously persisted value.

As far as I understand -out of previous releases docs- this used to be a feature. Am I missing something? Is there a particular reason why this feature was dropped?

In case it helps anybody, I finally got it working by slightly hacking the ListSelect2 widget:

class CharSelect2(autocomplete.ListSelect2):
    def filter_choices_to_render(self, selected_choices):
        # This turns the persisted charfield into something that can be
        # rendred as an <option id="foo">foo</option> element so as to fool
        # the inherited choices class.
        # Also allows the value to be cleared and left in blank
        self.choices = [(c, c) for c in selected_choices] + [("", "")]

The view I use is rather particular, just adapt it to your needs:

class DynamicAutocomplete(LoginRequiredMixin, autocomplete.Select2ListView):
    def get_list(self):
        # The inherited autocomplete.Select2ListView will already filter out strings
        # not containing self.q, but we trust the DB to be more efficient at this job
        # so the parent class is left a smaller data set and no actual work to do
        qs = DynamicValue.objects.filter(value__icontains=self.q)
        qs = qs.values_list('value', flat=True)
        qs = qs.distinct()
        qs = qs.order_by('value')
        list_ = list(qs)
        if self.q and self.q not in list_:
            # This allows new values to be created as the first option
            list_ = [self.q] + list_
        return list_

Then, in the form of my DynamicValue model I will simply use the CharSelect2 widget for the value field.

Now, in the light of this being a rather straightforward hack, could we discuss the feasibility of shipping it as a feature of this very library?

Sure, if you add documentation it will be usable by others, if you add tests it will not be broken by others

With your blessing I'll be glad to work on all of that. Sadly it won't be immediately, but I'll fight for a time window to work it out before 2020

Hey, guys! I found one crazy incompatibility. When you use CharSelect2 or TagSelect2 with lib like django-nested-admin it is working not correctly.

The case is looks like:
admin.py

class PaymentInfoInline(NestedTabularInline):
    model = PaymentInfo

class CompanyAdmin(NestedModelAdmin):
    form = CompanyForm
    inlines = [PaymentInfoInline]

forms.py
class CompanyForm(ModelForm): class Meta: model = Company fields = '__all__' widgets = { 'name': TagSelect2('company-autocomplete'), }

and other, I think doesn't matter

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cfblaeb picture cfblaeb  Â·  8Comments

raratiru picture raratiru  Â·  4Comments

Guilouf picture Guilouf  Â·  3Comments

ulziiburend picture ulziiburend  Â·  7Comments

durdenk picture durdenk  Â·  8Comments