Combine django mptt TreeNodeChoiceField with django-autocomplete-light ModelSelect2 widget

1.1k views Asked by At

A django-mptt TreeNodeChoiceField gives indented select options, whereas I can filter my results using django-autocomplete-light. However, the ModelSelect2 widget overwrites the rendered html, which removes the indentation.

I would like to combine the two. Any idea how I could achieve this?

models.py:

class Foo(MPTTModel):
    name = models.CharField(max_length=50)
    parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)

    class MPTTMeta:
        order_insertion_by = ['name']

forms.py:

class FooForm(forms.ModelForm):
    parent = TreeNodeChoiceField(queryset=Foo.objects.all(), widget=autocomplete.ModelSelect2(url='foo-autocomplete'))

    class Meta:
        model = Foo
        fields = ('name', 'parent', )
1

There are 1 answers

0
JIN On

I'll leave my solution here in case someone tries to achieve the same.

After digging into django-mptt source code and django-autocomplete-light examples, I found out that you can override the display text of the select options. Plus, django-mptt uses the level of the node to insert correct indentation. My model and form remain the same. I just had to override the get_result_label() method of my autocomplete view:

from mptt.settings import DEFAULT_LEVEL_INDICATOR

class FooAutocomplete(autocomplete.Select2QuerySetView):
    def get_result_label(self, item):
        level_indicator = DEFAULT_LEVEL_INDICATOR * item.level
        return level_indicator + ' ' + str(item)

    def get_queryset(self):
        qs = Foo.objects.all()
        if self.q:
            qs = qs.filter(name__istartswith=self.q)
        return qs