Reputation: 1689
I am trying to filter my queryset against an url with django REST but can't really get it to work.
I want to pass a string in the URL (a project name). According to this string, which is a foreign key, I want to filter my queryset (BuildingGroup).
I don't want to use query params but a url filter. I followed the docs but there is not so much on it on the site.
This is what I am trying:
class ListBuildingGroupProject(ListAPIView):
serializer_class = BuildingGroupSerializer
filter_fields = 'project'
def get_queryset(self):
project = self.kwargs['project']
building_groups = BuildingGroup.objects.filter(project=project)
result = building_groups.order_by('-creation_date')
return result
The line building_groups = BuildingGroup.objects.filter(project=project)
throws me a KeyError for project.
Here are my models. Note that BuildingGroup has one Project. A project can belong to many BuildingGroups.
class BuildingGroup(models.Model):
description = models.CharField(max_length=500, null=True, blank=True)
project = models.ForeignKey(Project, on_delete=models.CASCADE)
creation_date = models.DateTimeField(auto_now=False)
class Project(models.Model):
project_name = models.CharField(max_length=120, primary_key=True, unique=True)
start_date = models.DateTimeField(auto_now=False, null=True, blank=True)
end_date = models.DateTimeField(auto_now=False, null=True, blank=True)
and here my URL:
path('project/<str:project_name>', ListBuildingGroupProject.as_view(), name='building-group-project'),
Help is so much appreciated! Thanks in advance!
Upvotes: 0
Views: 1319
Reputation: 1145
You might want to have a look at this DRF documentation about this. It'll require to install Django Filters
You just need to declare in some rest_filters.py
from django_filters import rest_framework as filters
from .models import BuildingGroup
class BuildingGroupFilter(filters.FilterSet):
class Meta:
model = BuildingGroup
fields = {
"project__name":["exact","icontains"],
"project":["exact","in"]
}
Then within your ViewSet declaration: [...] from .rest_filters import BuildingGroupFilter
class ListBuildingGroupProject(ListAPIView):
serializer_class=BuildingGroupSerializer
filterset_class = BuildingGroupFilter
You can now enjoy a restfull behavior with:
{path_to_your_endpoint}?project__name__icontains="Hello World"
or {path_to_your_endpoint}?project__=[Project Id List]
To checkout how things works, filters are available in the browsable API.
Upvotes: 1
Reputation: 20966
In your url, your argument is called project_name
. This is what you should get from the kwargs. Beside, you want it to match the project.project_name:
def get_queryset(self):
project_name = self.kwargs['project_name']
building_groups = BuildingGroup.objects.filter(project__project_name=project_name)
result = building_groups.order_by('-creation_date')
return result
Upvotes: 1