Search code examples
djangodjango-filters

How to filter by request user in Django-filter model


Im using django-filter package and i want to know how can i pass queryset in ModelChoiceFilter of request user in my django-filter model

I updated with view list and this init functions doesnt have an affect for some reason

filters.py

class PresenceDateFilter(django_filters.FilterSet):

    work_date = DateTimeFromToRangeFilter(
        widget=django_filters.widgets.RangeWidget(
            attrs={'type': 'date', 'class': 'form-control'},
        ))

    class Meta:
        model = PresenceDetailInfo
        fields = ('presence_info__counter_presence',
                  'work_date',
                  )

models.py

class PresenceDetailInfo(models.Model):
    presence_info = models.ForeignKey(PresenceListInfo, default=None, null=True,
                                      on_delete=models.CASCADE, related_name='details_info')

class PresenceListInfo(models.Model):
    counter_presence = models.ForeignKey(CounterParty, default=None, null=True,
                                         on_delete=models.CASCADE)

class CounterParty(models.Model):
    counter_user = models.ManyToManyField(User, blank=True, related_name='counter_user')

views.py

class ShowPresenceInfoList(AccessMixin, ListView):
    model = PresenceDetailInfo
    template_name = 'common/presence_info.html'
    context_object_name = 'details_list'

    def get_context_data(self, *, object_list=None, **kwargs):
        context = super(ShowPresenceInfoList, self).get_context_data(**kwargs)
        list_of_dates = PresenceDateFilter(self.request.GET, queryset=self.get_queryset())
        context['form'] = list_of_dates.form
        context['dates'] = list_of_dates.qs

        return context

    def get_queryset(self):
        current_user = self.request.user
        current_counters = CounterParty.objects.filter(counter_user=current_user)

        if current_user.is_superuser:
            qs = PresenceDetailInfo.objects.all().select_related('presence_info', ).order_by(
                'work_date')
        else:
            qs = PresenceDetailInfo.objects.filter(presence_info__counter_presence__in=current_counters).select_related(
                'presence_info', ).order_by('work_date')
        word = PresenceDateFilter(self.request.GET, queryset=qs, request=self.request)
        return word.qs


Solution

  • you can pass it in the init inside the class PresenceDateFilter

    def __init__(self, data=None, queryset=None, *, request=None, user=None, prefix=None):
            super().__init__(data=data, queryset=queryset, prefix=prefix)
            self.filters['presence_info__counter_presence'].queryset = CounterParty.objects.filter(counter_user=user)
    

    You can customize the query, in the example it will return all the objects in the model and also get the user from request.user.