Django 中的条件嵌套过滤器

发布于 2024-11-09 18:47:30 字数 783 浏览 0 评论 0原文

我有一个 django 模型,可以说:

class Person(models.Model):
   first_name = models.CharField(max_length=25)
   last_name  = models.CharField(max_length=25)

并且,存在一个搜索表单,我可以在其中按名字、姓氏或两者搜索行。我注意到我可以在 django 查询集中链接过滤器,例如:

def search(request):
   list = Person.objects.filter(first_name= val1).filter(last_name=val2)

但是如果值 val1、val2 之一为空怎么办?我应该这样做:

def searh(request):
   if val1 != null and val2 == null:
      list = Person.objects.filter(first_name= val1)
   if val2 == null and val2 != null:
       list = Person.objects.filter(last_name= val2)
   if val2 != null and val2 != null:
       list = Person.objects.filter(first_name= val1).filter(last_name=val2)

有没有直接的方法可以做到这一点?

提前致谢

I have a django model, lets say:

class Person(models.Model):
   first_name = models.CharField(max_length=25)
   last_name  = models.CharField(max_length=25)

And, exists a search form, where I can search rows whether by first_name, by last_name or by both. I have noted that I can link filters in a django queryset, e.g:

def search(request):
   list = Person.objects.filter(first_name= val1).filter(last_name=val2)

But what if one of the values val1, val2 is null? Should I do something like:

def searh(request):
   if val1 != null and val2 == null:
      list = Person.objects.filter(first_name= val1)
   if val2 == null and val2 != null:
       list = Person.objects.filter(last_name= val2)
   if val2 != null and val2 != null:
       list = Person.objects.filter(first_name= val1).filter(last_name=val2)

Is there any direct way to do this?

thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夜深人未静 2024-11-16 18:47:31
def search(request, val1, val2):
    persons = Person.objects.all()
    if val1:
        persons = persons.filter(first_name=val1)
    if val2:
        persons = persons.filter(last_name=val2)
    return persons

这是有效的(并不是低效),因为查询集是惰性的

def search(request, val1, val2):
    persons = Person.objects.all()
    if val1:
        persons = persons.filter(first_name=val1)
    if val2:
        persons = persons.filter(last_name=val2)
    return persons

This works (isn't inefficient) because Querysets are lazy.

南冥有猫 2024-11-16 18:47:31

(免责声明:在 Python 2.7、Django 1.6 中进行了测试,尽管它通常应该可以工作)

我最近了解到以下直接适用于 OP 问题的构造:

def search(request, val1, val2):
    filter_args={}
    if val1:
        filter_args["first_name"]=val1
    if val2:
        filter_args["last_name"]=val2

    persons = Person.objects.filter(**filter_args)

    return persons

基本上,这将构造一个过滤器不止一个条件,即使您事先不知道 val1val2 是否都可用。它将使用连接(and)构建最具体的过滤器,而不需要额外的逻辑评估来克服 .filter(...).filter(...) 始终使用析取()来评估标准。例如,如果稍后您想将 age 添加到您的连词中,只需添加以下两行(并将 val3 添加到函数参数列表中):

    if val3:
        filter_args["age"]=val3

我正在使用这种方法在我正在努力取得巨大成功的一个项目中,我认为这些信息可能对有同样问题的新 Django 用户有用。

(Disclaimer: tested in Python 2.7, Django 1.6, although it should work in general)

I've been recently introduced to the following construct that directly applies to OP's issue:

def search(request, val1, val2):
    filter_args={}
    if val1:
        filter_args["first_name"]=val1
    if val2:
        filter_args["last_name"]=val2

    persons = Person.objects.filter(**filter_args)

    return persons

Basically, this will construct a filter with more than one criterion, even if you don't know a-priori whether both val1 and val2 will be available. It'll construct the most specific filter using conjunction (and) it can, without needing extra logic evaluation to overcome the fact that .filter(...).filter(...) always evaluates the criterions using disjunction (or). If later you want to add age to your conjunction, for instance, just add the following two lines (and val3 to the function argument list):

    if val3:
        filter_args["age"]=val3

I'm using this methodology in a project I'm working on to great success, and thought this information might be useful to newer Django users with this same question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文