GeoDjango дистанционный фильтр с дистанционным значением, хранящимся в модели – запрос

У меня есть модель Order , у которой есть Point Point Point и range IntegerField. Кроме того, существует модель UserProfile , которая имеет geo_location PointField. Теперь у меня есть экземпляр user , user . Я хочу выбрать все Order.origin , расстояние между Order.origin user.userprofile.geo_location Order.origin и user.userprofile.geo_location меньше значения (метров) в Order.range модели Order.range .

Таким образом, упрощенные модели:

 class Order(models.Model): origin = models.PointField() range = models.IntegerField(blank=True, default=10000) class UserProfile(models.Model): geo_location = models.PointField() 

У меня это работает (пройдя дистанцию ​​статически):

 >>> Order.objects.filter(origin__distance_lte=(user.profile.geo_location, D(m=3000))) 

Моя следующая (неудачная попытка) заключалась в использовании выражения F () для использования значения из поля Order.range :

 >>> Order.objects.filter(origin__distance_lte=(user.profile.geo_location, D(m=F('range')))) Traceback (most recent call last): File "<console>", line 1, in <module> File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/contrib/gis/measure.py", line 165, in __init__ self.m, self._default_unit = self.default_units(kwargs) File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/contrib/gis/measure.py", line 49, in default_units if not isinstance(value, float): value = float(value) TypeError: float() argument must be a string or a number 

Я думаю, проблема в том, что D () не лениво работает – я это понимаю. Поэтому я попытался просто взять исходное значение из поля range (целое число), которое я должен был работать, но:

 >>> Order.objects.filter(origin__distance_lte=(user.profile.geo_location, F('range'))) Traceback (most recent call last): File "<console>", line 1, in <module> File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/db/models/query.py", line 69, in __repr__ data = list(self[:REPR_OUTPUT_SIZE + 1]) File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/db/models/query.py", line 84, in __len__ self._result_cache.extend(self._iter) File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/db/models/query.py", line 273, in iterator for row in compiler.results_iter(): File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 680, in results_iter for rows in self.execute_sql(MULTI): File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 725, in execute_sql sql, params = self.as_sql() File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 68, in as_sql where, w_params = self.query.where.as_sql(qn=qn, connection=self.connection) File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/db/models/sql/where.py", line 92, in as_sql sql, params = child.as_sql(qn=qn, connection=connection) File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/db/models/sql/where.py", line 95, in as_sql sql, params = self.make_atom(child, qn, connection) File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/contrib/gis/db/models/sql/where.py", line 47, in make_atom spatial_sql = connection.ops.spatial_lookup_sql(data, lookup_type, params_or_value, lvalue.field, qn) File "/Users/danger/devel/.virtualenvs/proj/lib/python2.7/site-packages/django/contrib/gis/db/backends/postgis/operations.py", line 531, in spatial_lookup_sql raise ValueError('Argument type should be %s, got %s instead.' % (arg_type, type(value[1]))) ValueError: Argument type should be (<class 'decimal.Decimal'>, <class 'django.contrib.gis.measure.Distance'>, <type 'float'>, <type 'int'>, <type 'long'>), got <class 'django.db.models.expressions.F'> instead. 

Итак, как я могу выполнить то, что я пытаюсь сделать? Любая помощь приветствуется!

  • Матричное умножение для разреженных матриц в Python
  • Разница между типом данных 'datetime64 ' и '<M8 '?
  • Юникод, регулярные выражения и PyPy
  • Процесс преобразования простого скрипта Python в исполняемый файл Windows
  • Ошибка «неожиданного отступа» при использовании notepad ++ для создания функции django
  • Как разыменовать местоположение памяти из ctypes python?
  • Звездочки вне вызовов функций
  • многократные регулярные выражения python
  • One Solution collect form web for “GeoDjango дистанционный фильтр с дистанционным значением, хранящимся в модели – запрос”

    Я думаю, вам придется отказаться от некоторых SQL, чтобы делать то, что вы хотите, поскольку помощники GeoDjango не имеют способа сделать подходящий объект Distance который одновременно является объектом Django F (то есть полевым поиском). Вы не говорите, какую базу данных вы используете, но вот как вы это делаете с PostGIS:

     Order.objects.all().extra( where=['ST_Distance(origin, ST_PointFromText(%s, 4326)) <= CAST(range AS double precision) / 1000'], params=[user.profile.geo_location.wkt] ) 

    Давайте объясним, что здесь происходит, потому что это довольно тернистый. Справа слева:

    • .extra() позволяет добавлять дополнительные поля и ограничения в запрос; здесь мы добавляем ограничение
    • ST_Distance() – это функция PostGIS, которую оператор geoDjango distance_lte преобразует в (из документации Django )
    • ST_PointFromText() преобразует синтаксис WKT в объект PostGIS Geometry
    • 4326 является SRID по умолчанию для Django , но не для PostGIS, поэтому мы должны указать его
    • мы должны CAST ваше поле для двойной точности, потому что вы используете целое число
    • то мы должны разделить на 1000, чтобы преобразовать из метров в километры, что, я считаю, является тем, что нам нужно
    • В полях GeoDjango Point есть .wkt который дает их WKT-представление, которое нам было необходимо ранее в нашем ST_PointFromText()

    Обратите внимание, что в соответствии с документацией PostGIS ST_Distance() не использует индексы, поэтому вам может потребоваться расследование с использованием ST_DWithin() (оно задокументировано сразу после ST_Distance() ).

    Interesting Posts

    Как обрабатывать поступающие данные в реальном времени с помощью python pandas

    Повторная дискретизация Pandas с использованием numpy percentile?

    Простая система веб-сервера или веб-тестирования

    Как использовать переменную внутри регулярного выражения?

    Apyspyspark с использованием oracle jdbc для вывода данных. Драйвер не найден

    Марковские цепные стационарные распределения с scipy.sparse?

    Ускорение загрузчика python «import»

    Разработка Django IDE

    Документирование возвращаемого типа `tuple` в функции docstring для типа PyCharm

    ускорение последовательной проверки, если точка находится в форме в Python

    Кодирование файла изображения с помощью base64

    Комплекс бесконечности – смешные reslts – numpy ошибка?

    Определение того, является ли текст английским (навалом)

    библиотека или код python для чтения уже открытого файла Excel

    Как документировать вложенные классы с помощью autodoc Sphinx?

    Python - лучший язык программирования в мире.