Django QuerySet 过滤问题

3
我有一个模型,我想用搜索词来过滤它,通常是一个名字。但是在我的数据库中,first_namelast_name是两个单独的字段。
例如: search_term = 'Will Sm' db_persons记录: first_name = 'Will',last_name = 'Smith' 搜索词将能够检索到此记录。
如何实现呢? db_persons.objects.filter(__?__) 更新:
寻找一种连接字段并查询连接结果而不使用原始SQL的方法。

2个回答

6
如果您想在名字和姓氏中进行搜索,可以直接使用以下方法:

db_persons.objects.filter(first_name='Will', last_name='Smith')

如果你想在first_name或last_name中搜索,请使用Q对象

from django.db.models.query_utils import Q
db_persons.objects.filter(Q(first_name='will') | Q(last_name='will'))

根据评论更新: 一个简单的解决方案可能如下:

search_string = 'will smith'
query_list = search_string.split()
db_persons.objects.filter(Q(first_name__in=query_list) | Q(last_name__in=query_list))

如果您使用的是mysql,您可以使用search

但是如果用户搜索“威尔·史密斯”呢? - zentenk
嗯,不太符合我的要求,可能是因为我需要中文搜索词,这些词通常没有空格,并且包含名字和姓氏。我更希望能够将名字和姓氏连接成别名,并在这些别名上运行子查询以进行匹配,同时避免使用原始的 SQL。 - zentenk

2

一个简单的解决方案是在您的模型上添加另一个字段complete_name。在save时,您将通过连接first_namelast_name字段(不含任何空格,您需要从连接结果中剥离所有空格)来更新此字段。然后,您将使用search_term对该字段进行查询,但同时也去掉空格。

以下是一个简单的示例,以便让您了解一般思路:

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

    def save(self, *args, **kwargs):
        complete_name = '%s%s' % (self.first_name, self.last_name)
        self.complete_name = complete_name.replace(' ', '')
        super(Person, self).save(*args, **kwargs)

results = Person.objects.filter(complete_name__icontains=search_term.replace(' ', ''))

真不敢相信我没想到那个...现在我不需要子查询了,谢谢! - zentenk
另外,您可以详细说明在complete_name中放置了什么。这取决于您的用例,但您可以将first_namelast_name last_namefirst_name(例如,“WillSmith SmithWill”)放入其中。您还可以剥离字段和搜索术语中的重音符号和特殊字符。有时,使用此类技巧,您可以获得更好的结果。但这完全取决于您的用例和数据。我没有任何关于中文的经验。 - Etienne

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接