Search code examples
djangodjango-formsdjango-autocomplete-light

How to display additional fields about the M2M field in Django or override select2-results__option


I am looking to implement a feature to allow users to select other users and add them to their many-to-many field. The current state works in what I want it to do, but I want to be able to display additional information about the user they are selecting, and not just their username. Things like first_name, last_name, profile information, etc. - Ideally it would all be in the one line they see when adding the user to their m2m queue, such as:

John Smith | j.smith | [email protected]

as opposed to:

j.smith

I see the element select2-results__option and I'm curious if I can just override it with the additional information. If there is a clean way to do it through django, I'd prefer to do it that way, but open to anything really.

Views.py

class UserAutocomplete(autocomplete.Select2QuerySetView):
    def get_queryset(self):
        if not self.request.user.is_authenticated:
            return User.objects.none()
        qs = User.objects.all()
        if self.q:
            qs = qs.filter(Q(username__icontains=self.q) |
                           Q(first_name__icontains=self.q) |
                           Q(last_name__icontains=self.q))

        return qs

forms.py

class UserSurveyQueueForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user')
        super().__init__(*args, **kwargs)
        self.fields['queue'].queryset = User.objects.all().exclude(pk=user)
        self.fields['queue'].required = False

    class Meta:
        model = UserSurveyQueue
        fields = ('queue',)
        widgets = {
            'queue': autocomplete.ModelSelect2Multiple(
                url='user-autocomplete',
            ),
        }

Solution

  • Assuming this is for django-autocomplete-light, you can override the get_result_label method of your UserAutocomplete class to change the text shown in the dropdown.

    def get_result_label(self, result):
        return "{full_name}|{email}" .format(full_name = str(result), email = result.email)
    

    If you want it to be a pretty table, you're going to have to delve into dal's javascript.