【问题标题】:django_filters.FilterSet with Or Operatordjango_filters.FilterSet 与或运算符
【发布时间】:2016-05-26 10:27:56
【问题描述】:

我想用 django_filters.FilterSet 尝试 OR 语句,以创建“仅过滤器字段”(即:模型中不存在)。该字段应检查过滤器值是否与模型“真实字段”之一(其中两个)匹配

这是我的模型:

class Project(models.Model):
    id          = models.BigIntegerField(primary_key=True)
    name        = models.CharField(max_length=255) 
    cat         = models.ForeignKey(Category, related_name='projects', db_index=True, default=None, null=True)
    cat_main    = models.IntegerField(db_index=True, null=True)
    category_id = models.IntegerField(db_index=True, null=True)
    country     = models.CharField(max_length=16, null=True)
    added       = models.DateTimeField(auto_now_add=True)
    modified    = models.DateTimeField(auto_now=True)

这是我尝试实现的代码:

from django.db.models import Q

class ProjectCatFilter(django_filters.FilterSet):
    category = django_filters.MethodFilter(name='category', action='category_or_filter')
    class Meta:
        model = Project
        fields = ['cat_main', 'category_id']

    def category_or_filter(self, queryset, value):
        return queryset.filter(
            Q(category_id=value) | Q(cat_main=value)
        )

这是应该返回我的调用,其中“类别”匹配“cat_main”或“category_id”的项目

from server.ks.models import Project
projects = Project.objects.filter(category=1)
for p in projects:
    print p.name, p.id, p.cat_main, p.category_id

但我收到此错误:

django.core.exceptions.FieldError:无法将关键字“类别”解析为字段。选项有:name、cat、cat_id、cat_main、category_id、country、added、modified

那么 Project.objects.filter(category=1) 返回匹配 category_id 或 main_cat 字段(是否使用 FilterSet)的项目的正确/最佳方式是什么?

【问题讨论】:

  • 可能您还没有得到答案的原因是因为您正在使用第三方包来执行查询。你真的需要那个包吗?这里的很多 django 用户可能不熟悉它,因为 django 的 ORM 提供了出色的查询过滤功能,很少需要第三方插件。
  • 我显然愿意接受任何没有 django_filters 包的建议,只要 Project.objects.filter(category=1) 向我返回匹配 category_id 或 main_cat 字段的项目。
  • 那你为什么不只是做 Project.objects.filter(Q(pk=1) | Q(cat_main=whatever_you_want_it_to_be)) ?
  • 我不会直接拨打电话,它链接到我客户的 django rest 框架,我需要匹配一些强制我执行此模式的规范:SomeModel.objects.filter({field1:value, field2:value})
  • 因为客户为王,我不能自己去触碰其余的框架^^只用设计好的模式回答他的要求

标签: django django-queryset django-filters


【解决方案1】:

django-filter 的 FilterSet 在概念上类似于 Django 的内置 ModelForms。

  • ModelForms 生成用于创建或更新模型类实例的表单。
  • FilterSets 生成一个用于构造 orm 查询的表单。

您的示例调用不起作用,因为它没有调用 FilterSet - 没有要过滤的 category 字段。

手动测试过滤器集:

from server.ks.models import Project
from server.ks.filters import ProjectFilter

filterset = ProjectFilter(data={'category': '1'}, queryset=Project.objects.all())

for p in filterset.qs:
    print p.name, p.id, p.cat_main, p.category_id

【讨论】:

  • 感谢您的解释,我想我的问题在主要描述中远非明确(我刚刚相应地更新了它)。我真正的问题是找到最好的方法: Project.objects.filter(category=1) 返回匹配 category_id 或 main_cat 字段的项目。
  • 查看 ViewSet 代码会很有帮助。您说 DRF 自己进行过滤,但是 DRF 实际上委托给许多过滤器后端,包括一个用于 django-filter 的后端。您使用的是filter_class 还是filter_fieldsfilter_fields 只是自动为您生成一个filter_class。如果您已将 filter_class 设置为 ProjectFilter,则 /api/projects?category=1 应导致 Project.objects.filter(Q(category_id=value) | Q(cat_main=value))
猜你喜欢
  • 2017-04-13
  • 1970-01-01
  • 1970-01-01
  • 2013-07-03
  • 2010-11-29
  • 2011-04-20
  • 2017-03-29
  • 1970-01-01
  • 2019-05-03
相关资源
最近更新 更多