首页 > 解决方案 > 如何使用 django-filter 的 Filter.method 自定义过滤

问题描述

我正在使用 Django 构建网站,并且正在使用应用程序 django-filter 为我的网站产品构建过滤系统。基本上,我网站的所有用户都有一个localisation代表他们当前位置的属性(这个属性是来自 GeoDjango 的 PointField)。我希望用户能够过滤位于其位置附近的用户销售的产品。为此,我使用methoddjango_filters 的参数来自定义过滤。我认为我想要做的事情相当简单,但是由于 django-filter 的文档中缺少明确的示例,我在实现它时遇到了麻烦。您可以在下面找到我迄今为止尝试过的内容以及使用的模型,以便您了解我所做的。

模型之间的关系结构有点复杂,但我认为您不需要它来理解我的问题。以下是结构的完整说明,以防万一有用:该User模型链接到UserAdvanced为用户提供高级功能的模型。该UserAdvanced模型可选地链接到Chef代表可以销售产品的用户的模型。最后,Chef模型可以链接到Plat代表用户销售的产品的模型。我想根据模型的属性过滤Plat产品。localisationUserAdvanced

models.py(仅相关部分)

class UserAdvanced(models.Model):
    user = models.OneToOneField(User, on_delete = models.CASCADE)
    localisation = models.PointField(blank = True, null = True)

class Chef(models.Model):
    userAdv = models.OneToOneField(UserAdvanced, on_delete = models.CASCADE)

class Plat(models.Model):
    chef = models.ForeignKey(Chef, on_delete = models.CASCADE)

过滤器.py

class PlatFilter(django_filters.FilterSet):
    titre = django_filters.CharFilter(
        field_name='titre', label='Mot clé :', lookup_expr='icontains',
        widget=forms.TextInput(attrs={'class': 'form-control'}),
    )

    distance = django_filters.NumberFilter(
        method='distance_filter', label='Distance maximum en mètres de votre position (n\'oubliez pas de la mettre à jour si nécessaire)',
        widget=forms.NumberInput(attrs={'class': 'form-control'}),
    )

    class Meta:
        model = Plat
        fields = ['titre', 'nb_portions', 'date_prep']

    def distance_filter(self, queryset, name, value):
        return queryset.filter(chef__useradvanced__localisation.distance(request__user__useradvanced__localisation)__lte = value)

我正在使用 GeoDjango 的距离函数计算 2 个点之间的距离,并且我正在尝试过滤查询集以获取该距离低于或等于提供的值的产品。目前,我有一个SyntaxError: invalid syntax. 就像我说的,我认为解决方案相当简单,但由于互联网上缺乏文档,我很难找到它。一点帮助将不胜感激。

提前致谢 !

标签: djangodjango-filter

解决方案


你的问题在最后一行

def distance_filter(self, queryset, name, value):
    return queryset.filter(chef__useradvanced__localisation.distance(request__user__useradvanced__localisation)__lte = value)
    #                                                                                                          ^here

__lte是错的


推荐阅读