Django -filter: фильтрация с использованием функции с атрибутом запроса - PullRequest
0 голосов
/ 28 января 2020

Я создаю сайт с Django, и у меня есть небольшая проблема с фильтрацией. У меня есть модель User с атрибутом location, и я хочу, чтобы пользователь мог искать других пользователей рядом со своим местоположением. У меня есть функция distance(location1, location2), вычисляющая расстояние между двумя точками. Мне нужен пользователь A, чтобы искать всех пользователей B, для которых расстояние (locationA, locationB) ниже значения, выбранного A. Мне нужно получить locationA из запроса, и это в сочетании с использованием функции внутри фильтра делает вещи немного сложнее для начинающего, как я. Вот что я пробовал до сих пор:

import django_filters

class LocationFilter(django_filters.FilterSet):
    distance = django_filters.NumberFilter(
        field_name='location', method='distance_filter', label='...',
        widget=forms.NumberInput(attrs={'class': 'form-control'}),
    )

    class Meta:
        model = User
        fields = [SOME ATTRIBUTES]

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

В настоящее время я получаю SyntaxError: invalid syntax. Я думаю, что неправильно использую Filter.method django -фильтра, но отсутствие документации по inte rnet (кроме базовых c примеров) затрудняет понимание того, что я делаю неправильно. Я был бы очень признателен за помощь.

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

РЕДАКТИРОВАТЬ:

models.py

from django.contrib.gis.db import models 

class User(models.Model):
    location = models.PointField(blank = True, null = True)

Ответы [ 2 ]

0 голосов
/ 28 января 2020

Трудно или невозможно сделать то, что вы просите. Фильтрация Queryset - это абстракция, которая генерирует запрос SQL для отправки в базу данных. База данных возвращает результаты выполнения этого запроса. База данных не имеет доступа к вашему Python контексту.

Так что вам нужно express ваша функция расстояния в SQL.

Если вы используете PostgreSQL Я считаю, это может быть встроено (GeoGIS), но это будет за счет того, что ваша Django спецификация базы данных приложения c.

Возможно, возможно закодировать простую функцию расстояния, используя F выражения и функции базы данных . Обратитесь к документации Django. (Глубоководное предупреждение). Альтернативой является получение всех возможных кандидатов из базы данных с помощью простого фильтра, а затем дополнительная фильтрация результатов в Python с помощью сложного алгоритма.

0 голосов
/ 28 января 2020
 def distance_filter(self, queryset, name, value):
    return queryset.filter(location.distance(request__user__location)__lte = value)

Какое «место» вы достигаете там? может быть, self.location? Я смущен извините.

...