【问题标题】:Django filter query if filter parameter existsDjango过滤器查询是否存在过滤器参数
【发布时间】:2019-12-19 16:30:44
【问题描述】:

我正在尝试使用多个过滤器参数(例如名称、年龄、身高)创建一个 django 过滤器。但是,我只想按参数过滤(如果存在)...

在我的初始化中:

def __init__(self, name=None, age=None, height=None):
    self.name = name
    self.age = age
    self.height = height

在我的查询中:

Person.objects.filter(name=self.name, age=self.age, height=self.height)

但是,问题是由于参数在构造函数中是可选的,过滤器有可能正在寻找我不想要的 None 值。如果name='mike'age=25height=None,我只希望过滤器使用nameage参数并排除height。比如:

Person.objects.filter(if self.name: name=self.name, if self.age: age=self.age, if self.height: height=self.height)

这可能吗?或者我是否需要首先检查每个变量是否存在并且每个可能的过滤器查询都有不同的情况?

谢谢!

【问题讨论】:

    标签: python django django-models django-filters


    【解决方案1】:
    from django.db import models as dmodels
    filters = dmodels.Q(age=age) & dmodels.Q(name=name)
    if height:
        filters &= dmodels.Q(height=height)
    Person.objects.filter(filters)
    

    see here

    【讨论】:

    • 如果您有 N 个字段怎么办?
    【解决方案2】:

    如果您想构建通用解决方案,请使用Custom model manager

    #manager.py
    from django.db.models import Manager
    
    
    class CustomManager(Manager):
        def custom_filter(self, *args, **kwargs):
            updated_kwargs = {k: v for k, v in kwargs.items() if v is not None}
            return super().filter(*args, **updated_kwargs)

    将此管理器附加到您的模型类中,

    #models.py
    class Person(models.Model):
        objects = CustomManager()
        # other fields

    然后,使用这个custom_filter(...)方法进行查询,类似于内置的filter()

    # example usage
    Person.objects.custom_filter(name=self.name, age=self.age, height=self.height)

    注意:custom_filter方法将省略所有None

    的值

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-17
      • 2019-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-14
      相关资源
      最近更新 更多