0

I've a LearnerInstance model:

class LearnerInstance(models.Model):
    learner = models.ForeignKey(Learner, on_delete=models.CASCADE)
    aim = models.ForeignKey(Aim, on_delete=models.CASCADE)
    ...

    class Meta:
        unique_together = ("learner", "aim")

    def __int__(self):
        return self.learner

    def name(self):
        return f"{self.learner.firstname} {self.learner.surname}"

views.py

class GroupDetailView(FilterView):
    model = LearnerInstance
    template_name = "group_detail.html"
    table = LearnerGroupTable
    filterset_class = LearnerInstanceFilter

    def get_context_data(self, **kwargs):
        context = super(GroupDetailView, self).get_context_data(**kwargs)
        queryset = LearnerInstance.objects.filter(
            learner__group__short_name=self.kwargs["pk"])
        f = LearnerInstanceFilter(
            self.request.GET, queryset=queryset.filter(aim=self.request.GET.get("aim")))
        context["table"] = LearnerGroupTable(f.queryset)
        context["group"] = Group.objects.filter(short_name=self.kwargs["pk"]).values()
        return super().get_context_data(**context)

filters.py

class LearnerInstanceFilter(django_filters.FilterSet):

    class Meta:
        model = LearnerInstance
        fields = ["aim"]

Question: How do I change the filter to show only the distinct aim options returned by the queryset (all learner instances related to a selected group) within the get_context_data?

The database contains all possible aims which are offered through the filter (I know this is due to the filter being linked to the model and aim field), I want to be presented with only a list of aims that are unique to the learners within the current context.

Queryset shows unique_aims but filter is still showing all options

1 Answer 1

0

updated as your question:

In my opinion, to modify the filter so that it only shows distinct aim options related to the current context, you need to override the filter's queryset and adjust your get_context_data method to achieve that:

views.py

from django_filters import rest_framework as filters

class GroupDetailView(FilterView):
    model = LearnerInstance
    template_name = "group_detail.html"
    table = LearnerGroupTable
    filterset_class = LearnerInstanceFilter

    def get_context_data(self, **kwargs):
        context = super(GroupDetailView, self).get_context_data(**kwargs)

        # Filter LearnerInstances based on the group
        queryset = LearnerInstance.objects.filter(
            learner__group__short_name=self.kwargs["pk"]
        )

        learner_instanes_filtred = LearnerInstanceFilter(
            self.request.GET,
            queryset=queryset
        )

        context["table"] = LearnerGroupTable(learner_instanes_filtred.qs)
        context["group"] = Group.objects.filter(short_name=self.kwargs["pk"]).values()
        context["filter"] = learner_instanes_filtred

        return context

and about

filters.py

class LearnerInstanceFilter(django_filters.FilterSet):
    aim = django_filters.ModelChoiceFilter(queryset=Aim.objects.none())

    class Meta:
        model = LearnerInstance
        fields = ["aim"]

    def __init__(self, *args, **kwargs):
        queryset = kwargs.pop('queryset', None)
        super().__init__(*args, **kwargs)
        
        if queryset is not None:
            unique_aims = queryset.values_list('aim', flat=True).distinct()
            self.filters['aim'].queryset = Aim.objects.filter(id__in=unique_aims)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for getting back to me Mahrez. I am still seeing all aims listed within the filter choices. The filter is working fine now, thank you - I am able to filter the table and show only the rows for the selected aim but I'd still like to be able to limit the options given in the filter to those within unique_aims. I've added a photo to show what I can see.
Perfect - Thank you so much!! Really do appreciate your time and help.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.