【问题标题】:Django Rest Framework filter class method with two parameters带有两个参数的 Django Rest Framework 过滤器类方法
【发布时间】:2017-06-13 13:44:11
【问题描述】:

我有一个与许多模型相关的模型,如下所示:

class Father:
   son = # Foreign key to Son model

class Son:
   @property
   def son_daughters:
      if ... :
         obj = TypeA.objects.get(...)
      elif ... :
         obj = TypeB.objects.get(...)
      else:
         obj = TypeC.objects.get(...)

      return obj

我想从女儿姓名或类型中获取父亲数据。我有这个过滤器类,我需要发送两个与女儿相关的查询集参数,以便获取女儿 ID 并将其作为过滤器应用于父亲。这是我的过滤器类:

class FatherFilter(django_filters.rest_framework.FilterSet):
   def daughter(self, method_name, args, **kwargs):

        print(method_name, args, kwargs)
        ...

   daughter_id = django_filters.NumberFilter(method=daughter)

但是当我调用这个端点时,我只得到一个查询参数而不是全部。

有没有办法在这个方法中获取查询参数而不是一个?

提前致谢。

【问题讨论】:

  • 这似乎与 DRF 无关。 django-filters 是一个完全独立的包。
  • Django Rest 将 django-filters 实现为一个包来使用 Django Filter 类,请验证:django-rest-framework.org/api-guide/filtering/…
  • 对于历史/上下文,django-filter 是一个完全独立的包。但是,DRF 过去提供了一个“过滤器后端”,使您可以轻松地将 django-filter 与 DRF 集成。此过滤器后端已被移至 django_filters.rest_framework 子包。您在这里遇到的问题与 DRF 没有直接关系。
  • 目前尚不清楚您在这里尝试做什么。您能否提供一个示例 URL 或查询字符串以及应该由过滤器集生成的查询集?至于您的问题,您可以直接访问self.data,尽管我不建议这样做,因为您会绕过验证。
  • 谢谢,@Sherpa。抱歉,我不够清楚,我发布了此代码作为所需结果的示例,但真正的代码依赖于许多模型和视图,这些模型和视图对于理解最终结果可能更复杂。我找到了实现这一目标的方法,虽然它可能不是最好的方法,但它现在有效。我将在下面发布答案。

标签: python django django-rest-framework django-filter


【解决方案1】:

为了实现这一点,我发现 Django Rest Framework 有一个从 django_filters 扩展而来的类。此类称为 BaseFilterBackend ,可用于扩展默认后端以过滤任何请求。所以我所做的是添加一个从 BaseFilterBackend 扩展的类,如下所示:

from rest_framework import filters

class FatherFilterBackend(filters.BaseFilterBackend):
   def filter_queryset(self, request, queryset, view):
      daughter_id = request.query_params.get("daughter_id", None)
      daughter_name = request.query_params.get("daughter_name", None)

      if daughter_id and daughter_name:
         kwargs = {
            daughter_name: daughter_id
         }
         queryset = queryset.filter(**kwargs)

      return queryset

此过滤器将在其他过滤器之前应用,因此即使您使用的是 FilterSet 类,您也不会丢失 BaseFilterBackend 中的过滤器。这个解决方案的问题在于依赖于 rest_framework.filters 包,一个与 django_filters 无关的过滤器。

这可能不是实现此目标的最佳方式,因此如果您有更好的想法,请添加它们以帮助其他有类似问题的人。

【讨论】:

  • 谢谢。 DRF 文档没有提到导入的来源!
猜你喜欢
  • 2019-05-15
  • 2018-02-23
  • 2014-08-16
  • 2018-07-28
  • 2021-07-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2018-10-03
相关资源
最近更新 更多