Contents

django-filter: Filtering Fields by User Id

Contents

I was working with a table page. In this page I have a filter form that showing a dropdown field that show a list of device name and when the user select one of them, the data of the table would be filtered based on the device id alongside with other filtered fields. I used django-filter to create the filter. The first implementation were like this.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class MeasurementFilter(django_filters.FilterSet):
    start_date = DateFilter(
        field_name="date", lookup_expr=("gt"), widget=DateInput(attrs={"type": "date"})
    )
    end_date = DateFilter(
        field_name="date", lookup_expr=("lt"), widget=DateInput(attrs={"type": "date"})
    )

    class Meta:
        model = Measurement
        fields = ["device"]

This implementation of the filter has a big issue. It showed all devices in my database in the device field of the filter. This is a serious problem as we don’t want any logged user see other users devices. After several times trying to solve this problem, I found an elegant solution to this problem. We can define a function to override the default queryset. In this method, we can filter the field to show only the devices owned by the user that is currently logged in. We can use request.user.id to get the user id of the logged in user and user it for filtering the device list. The correct implementation looks like this.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def devices(request):
    return Device.objects.filter(user_id=request.user.id)

class MeasurementFilter(django_filters.FilterSet):
    device = ModelChoiceFilter(field_name="device", queryset=devices)
    start_date = DateFilter(
        field_name="date", lookup_expr=("gt"), widget=DateInput(attrs={"type": "date"})
    )
    end_date = DateFilter(
        field_name="date", lookup_expr=("lt"), widget=DateInput(attrs={"type": "date"})
    )    

    class Meta:
        model = Measurement
        fields = []

Hopefully, it can help you to solve similar problem. Don’t forget to import the involved models to your filters.py file.