Как настроить фильтрацию с помощью Filter.method django-filter

Я создаю веб-сайт с Django и использую приложение django-filter для создания системы фильтрации для продуктов моего веб-сайта. По сути, у всех пользователей моего веб-сайта есть атрибут localisation, который представляет их текущее местоположение (это атрибут PointField из GeoDjango). Я хотел бы, чтобы пользователь мог фильтровать товары, продаваемые пользователями, находящимися рядом с ним. Для этого я использую аргумент method django_filters для настройки фильтрации. Я думаю, что то, что я хочу, довольно просто сделать, но у меня проблемы с его реализацией из-за отсутствия явных примеров в документации django-filter. Ниже вы можете найти то, что я пробовал до сих пор, с использованными моделями, чтобы вы могли понять, что я сделал.

Структура отношений между моделями немного сложна, но я не думаю, что вам это нужно, чтобы понять мой вопрос. Вот полное объяснение структуры на случай, если это будет полезно: модель User связана с моделью UserAdvanced, обеспечивающей расширенные функции для пользователя. Эта модель UserAdvanced опционально связана с моделью Chef, которая представляет пользователей, которые могут продавать продукты. Наконец, модель Chef можно связать с моделью Plat, которая представляет продукты, продаваемые пользователем. Я хочу отфильтровать продукт Plat на основе атрибута localisation модели UserAdvanced.

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, и пытаюсь отфильтровать набор запросов, чтобы получить продукты, для которых это расстояние меньше или равно предоставленному значению. В настоящее время у меня SyntaxError: invalid syntax. Как я уже сказал, я думаю, что решение довольно простое, но мне трудно найти его из-за отсутствия документации в Интернете. Небольшая помощь будет принята с благодарностью.

Заранее спасибо !


person Julien Mertz    schedule 26.01.2020    source источник


Ответы (1)


Ваша проблема здесь, в последней строке

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

__lte это неправильно

person Sardorbek Imomaliev    schedule 12.02.2020