[英]Django Rest how to order on a model method
使用Django Rest Framework是否可以對模型方法進行order
? 我已經嘗試過了,DRF要求它必須在現場。 因此給出錯誤:
無法將關鍵字“距離”解析為字段。
查看類ActivityListView(ListCreateView):
queryset = model_activity.objects.all()
serializer_class = ActivityListSerializer
filter_backends = (OrderingFilter,)
# default ordering
ordering = ('distance')
序列化器
class ActivityListSerializer(serializers.ModelSerializer):
distance = serializers.SerializerMethodField('_get_distance')
class Meta:
model = model_activity
fields = ('id', 'distance')
def _get_distance(self, obj):
return obj.get_distance(user=self.context['request'].user)
我認為答案是否定的, OrderingFilter
可幫助您生成queryset(本質上是SQL)。
但是通過模型方法進行排序意味着django需要將所有記錄從數據庫加載到內存中,然后在內存中對其進行排序。
如果那里有大量記錄,則您的筆錄將非常慢。
可以在SQL函數中實現它嗎? 這樣您就可以通過SQL函數注釋該值,然后對其進行排序。
from django.db import models
class ActivityListView(ListCreateView):
queryset = model_activity.objects.all()
serializer_class = ActivityListSerializer
filter_backends = (OrderingFilter,)
# default ordering
ordering = ('distance')
def filter_queryset(self, queryset):
cur_latitude, cur_longitude = self.get_cur_latitude_longitude()
# add the distance field to sql dataset result, so that we can order by it
queryset = queryset.annotate(
distance=models.Func(cur_latitude, cur_longitude, 'latitude', 'longitude', function='get_distance')
)
return super(ActivityListView, self).filter_queryset(self, queryset)
並且不要忘記創建sql函數,這是postgresql的示例:
CREATE OR REPLACE FUNCTION public.geodistance(alat float8, alng float8, blat float8, blng float8)
RETURNS float8
AS
$BODY$
SELECT
case when $1 is null or $2 is null or $3 is null or $4 is null
then 9999999
else
asin(
sqrt(
sin(radians($3-$1)/2)^2 +
sin(radians($4-$2)/2)^2 *
cos(radians($1)) *
cos(radians($3))
)
) * 7926.3352
end
AS distance;
$BODY$
LANGUAGE sql IMMUTABLE;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.