rest_framework пользовательский заказ_би

#django-rest-framework #django-filters

Вопрос:

давайте посмотрим, смогу ли я правильно задавать вопросы?

model.py

 class Point(models.Model):   name = models.CharField(  "nome del sistema",  max_length=128,  )  x = models.FloatField(  "cordinata spaziale x",  )  y = models.FloatField(  "cordinata spaziale y",  )  z = models.FloatField(  "cordinata spaziale z",  )  distance = float(0)     def __str__(self) -gt; str:  return f"{self.name}"   @property  def get_distance(self):  return self.distance   @get_distance.setter  def get_distance(self, point):  """  ritorna la distanza che ce tra due sistemi  """  ad = float((point.x-self.x) if point.x gt; self.x else (self.x-point.x))  bc = float((point.y-self.y) if point.y gt; self.y else (self.y- point.y))  af = float((point.z-self.z) if point.z gt; self.z else (self.z-point.z))  return (pow(ad,2) pow(bc,2) pow(af,2))**(1/2)   class Meta:  verbose_name = "point"  verbose_name_plural = "points"  

в конкретной модели есть два определения, которые вычисляют, сохраняют и возвращают расстояние относительно точки, которую мы проходим.

wenws.py

 class PointViewset(viewsets.ModelViewSet):  """  modelo generico per un systema  """  queryset = Point.objects.all()  serializer_class = PointSerializers  filterset_class = PointFilter  

в wenws не так много особенного, чтобы объяснять и основывать базу, единственное, что мы должны сказать, и что в качестве фильтров я использую «django_filters»

filters.py

 import django_filters as filters import Point  class CustomOrderFilter(filters.CharFilter):   def filter(self, qs:QuerySet, value):  if value in ([], (), {}, '', None):  return qs  try:  base = qs.get(name=value)  for point in qs:  point.get_distance = base  qs = sorted(qs, key= lambda x: x.get_distance)   except Point.DoesNotExist:  qs = qs.none()  return qs   class PointFilter(filters.rest_framework.FilterSet):   security = filters.ChoiceFilter(choices=security_choices  point= CustomCharFilter(  label = "point"  )   class Meta:  model = Point  fields = {  'name':['exact'],  }   

теперь сложная вещь с «CustomCharFilter» Я передаю в http-запросе имя системы, которое затем возвращается мне в фильтре в качестве значения после того, как я проверю, что оно не пустое, и я начну с возврата точки, с которой я прошел, base = qs.get ( name = value) чтобы затем вычислить и сохранить расстояние для каждой точки с помощью point.get_distance = base '' on the inside of the for, at the end I reorder the QuerySet with qs = сортировка (qs, ключ = лямбда x: x.get_distance) «проблема в том, что как с этим, так и с другим способом, который я попробовал, набор запросов «преобразуется» в список, и это меня не устраивает, так как я должен возвращать набор запросов в порядке, который я хочу. Я не знаю, как поступить иначе, так как order_by я не могу его использовать, так как расстояние не находится внутри базы данных, может ли кто-нибудь мне помочь?

Ответ №1:

Таким образом, проблема в том, что вы хотите отфильтровать функцию python, которая не может быть выполнена в запросе, так как они говорят только на SQL.

Простое медленное решение-выполнить фильтрацию на python, это может сработать, если есть всего несколько точек.

 points = list(Point.objects.all()) points.sort(cmp=comparison_function)  

Реальное решение состоит в том, чтобы перенести эту математику в Djangos ORM и аннотировать ваш набор запросов расстоянием до заданной точки, это довольно сложный запрос, если вы сообщите нам, какой сервер базы данных вы используете, мы, вероятно, сможем помочь вам и в этом.

ps. В python есть abs() функция для получения абсолютного значения вместо if/else в get_distance

Комментарии:

1. здравствуйте, спасибо за ваш ответ, тогда, если я позже превращу его в список, он вернет мне ошибку для того, кто говорит, что ему нужен набор запросов, а не список, и база данных, которую я использую, — MySQL

2. привет, смотри, я обновил свой прогресс, достигнутый сегодня, и я попытался лучше объяснить свою проблему

3. Я полностью понимаю проблему, но вам нужно будет либо сделать все это на python, поэтому после оценки любых наборов запросов, либо в наборе запросов, но затем вам нужно использовать для этого ORM и выполнить математику в SQL.