rest_framework 自定义 order_by
rest_framework custom order_by
看看我能不能把问题问对?
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) -> 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 > self.x else (self.x-point.x))
bc = float((point.y-self.y) if point.y > self.y else (self.y- point.y))
af = float((point.z-self.z) if point.z > 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"
在特定模型中有两个 defs 计算、保存和 return 相对于我们通过它们的点的距离
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 请求中传递了系统的名称,然后 return 在我检查它不为空之后在过滤器中将其作为值发送给我并且我从 return 开始,我已经通过 base = qs.get ( name = value)
然后使用 point.get_distance = base '' on the inside of the for, at the end I reorder the QuerySet with
qs = sorted (qs, key = lambda x: x.get_distance) 计算并保存每个点的距离 '' 这种方式和我尝试过的另一种方式的问题QuerySet 它 'transforms' 到一个列表中,这不适合我,因为我必须按照我想要的顺序 return 一个 QuerySet。我不知道该怎么做,因为 order_by 我不能使用它,因为距离不在数据库内
有人可以帮我吗?
所以问题是你想从 python 函数中过滤,这不能在查询中完成,因为它们只会说 SQL.
简单而缓慢的解决方案是在 python 中进行过滤,如果只有几个点,这可能会奏效。
points = list(Point.objects.all())
points.sort(cmp=comparison_function)
真正的解决方案是将该数学移植到 Djangos ORM 并用到给定点的距离注释您的查询集,这是一个非常高级的查询,如果您告诉我们您使用的数据库服务器,我们可能会帮助您还有那个。
ps。 python中有一个abs()
函数来获取绝对值,而不是get_distance
中的if/else
看看我能不能把问题问对?
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) -> 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 > self.x else (self.x-point.x))
bc = float((point.y-self.y) if point.y > self.y else (self.y- point.y))
af = float((point.z-self.z) if point.z > 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"
在特定模型中有两个 defs 计算、保存和 return 相对于我们通过它们的点的距离
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 请求中传递了系统的名称,然后 return 在我检查它不为空之后在过滤器中将其作为值发送给我并且我从 return 开始,我已经通过 base = qs.get ( name = value)
然后使用 point.get_distance = base '' on the inside of the for, at the end I reorder the QuerySet with
qs = sorted (qs, key = lambda x: x.get_distance) 计算并保存每个点的距离 '' 这种方式和我尝试过的另一种方式的问题QuerySet 它 'transforms' 到一个列表中,这不适合我,因为我必须按照我想要的顺序 return 一个 QuerySet。我不知道该怎么做,因为 order_by 我不能使用它,因为距离不在数据库内
有人可以帮我吗?
所以问题是你想从 python 函数中过滤,这不能在查询中完成,因为它们只会说 SQL.
简单而缓慢的解决方案是在 python 中进行过滤,如果只有几个点,这可能会奏效。
points = list(Point.objects.all())
points.sort(cmp=comparison_function)
真正的解决方案是将该数学移植到 Djangos ORM 并用到给定点的距离注释您的查询集,这是一个非常高级的查询,如果您告诉我们您使用的数据库服务器,我们可能会帮助您还有那个。
ps。 python中有一个abs()
函数来获取绝对值,而不是get_distance