Django-filter,如何进行多字段搜索?(使用django-filter!)

29

我该如何使用Django-filter从以下模型中进行多字段搜索:

class Location(models.Model):
    loc = models.CharField(max_length=100, blank=True)
    loc_mansioned = models.CharField(max_length=100, blank=True)
    loc_country = models.CharField(max_length=100, blank=True)
    loc_modern = models.CharField(max_length=100, blank=True)
我需要在我的网站上添加一个输入框,可以搜索所有“Location”模型的字段。
4个回答

57

你可以创建一个自定义过滤器,然后像这样做:

from django.db.models import Q
import django_filters


class LocationFilter(django_filters.FilterSet):
    q = django_filters.CharFilter(method='my_custom_filter', label="Search")

    class Meta:
        model = Location
        fields = ['q']

    def my_custom_filter(self, queryset, name, value):
        return queryset.filter(
            Q(loc__icontains=value) |
            Q(loc_mansioned__icontains=value) | 
            Q(loc_country__icontains=value) | 
            Q(loc_modern__icontains=value)
        )

这将按照这些字段中的任何一个进行过滤。您可以使用任何您想要的东西替换 icontains


谢谢!它有效了! 我应该把icontains放在哪里? - Medevin
@Medevin:你可以使用containsstartswithequals等许多其他字段查找方式,而不是field lookup icontains。请点击链接查看其他字段查找方式。 - Morten Engelsmann
实际上,这个答案有一个缺陷。它在返回语句中使用了 Location.objects 而不是 queryset。 - boatcoder
你在 Meta 类中指定模型是做什么的?如果没有 Meta 类,这仍然有效吗?我的理解是,在 django-filters 中,Meta 类用于使用指定模型中的字段,但在这种情况下,“q”是一个新字段,不在“Location”模型中。 - Aikanáro

3

这很完美。我正在尝试做一个动态过滤器,如果选中,则切换以获取搜索中的另一个字段。类似于这样:

def my_custom_filter(self, queryset, name, value):
    return Reference.objects.filter(
        Q(ref_title__icontains=value))

def my_custom_filter_with_description(self, queryset, name, value):
    return Reference.objects.filter(
        Q(ref_title__icontains=value) | Q(complete_description__icontains=value))

但我不知道如何将开关与类连接起来。

你正在使用 ModelName.objects.filter,但为什么没有使用 queryset 参数呢?在我的情况下,我得到了一个空的 queryset 参数。 - Nikhil Bhardwaj

2
由于您已将Location定义为对象,要按多个字段进行过滤,请使用filter方法。
filterlocation = Location.objects.filter(loc=formloc, loc_mansioned=formlocmansioned, loc_country=formloccountry, loc_modern=formlocmodern)

但是你需要实现一种更好的方式来使用这些过滤器,这样只有符合所有条件的结果才会被显示。


1

另一种解决方案,因为另一个无法直接工作:

@staticmethod
def filter_stock(qs, name, value):
    return qs.filter(
        Q(ticker__exact=value) | Q(company__iexact=value)
    )

在搜索时,如果您通过键入进行搜索,则必须避免使用“__exact”而应改用“contains”或“icontains”查询。 - Shedrack

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