如何在 Django REST 中使用外键字段过滤 URL,正确覆盖 get_queryset 方法

How to filter against URL with foreign key field in Django REST, overwriting get_queryset method correctly

我正在尝试使用 django REST 针对 url 过滤我的查询集,但无法真正让它工作。

我想在URL(项目名称)中传递一个字符串。根据这个字符串,它是一个外键,我想过滤我的查询集(BuildingGroup)。

我不想使用查询参数,而是使用 url 过滤器。我遵循了文档,但网站上没有太多内容。

这就是我正在尝试的:

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

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)


这是我的 URL:

    path('project/<str:project_name>', ListBuildingGroupProject.as_view(), name='building-group-project'),

非常感谢您的帮助!提前致谢!

在你的 url 中,你的论点叫做 project_name。这是你应该从 kwargs 那里得到的。此外,您希望它匹配 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

你可能想看看这个DRF documentation。 需要安装 Django Filters

你只需要声明一些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"]
       }

然后在您的 ViewSet 声明中: [...] 从 .rest_filters 导入 BuildingGroupFilter

class ListBuildingGroupProject(ListAPIView):
    serializer_class=BuildingGroupSerializer
    filterset_class = BuildingGroupFilter

您现在可以通过以下方式享受宁静的行为: {path_to_your_endpoint}?project__name__icontains="Hello World"{path_to_your_endpoint}?project__=[Project Id List]

要检查其工作原理,可浏览 API。

中提供了过滤器