Django_filters.Filterset with context data from FilterView
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.
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)
queryset = LearnerInstance.objects.filter(
learner__group__short_name=self.kwargs["pk"]
)
unique_aims = queryset.values_list('aim', flat=True).distinct()
f = LearnerInstanceFilter(
self.request.GET,
queryset=queryset.filter(aim__in=unique_aims)
)
context["table"] = LearnerGroupTable(f.qs)
context["group"] = Group.objects.filter(short_name=self.kwargs["pk"]).values()
context["filter"] = f # Include the filter in the context if needed for rendering
return context