如何从序列化程序字段订购Django Rest Framework queryset? [英] How to order django rest framework queryset from serializer field?
问题描述
如何从序列化程序字段订购Django QuerySet
?由于字段太复杂,我无法使用 annotate
来订购 QuerySet
,并且无法将值存储在
How can I order a Django QuerySet
from a serializer field? Since the field is too complicated, I couldn't order the QuerySet
using annotate
and I cannot store the value in the model as well.
编辑:
序列化器
class DrinkListModelSerializer(serializers.ModelSerializer):
count_need = serializers.SerializerMethodField()
url = drink_detail_url
class Meta:
model = Drink
fields = [
'name',
'count_need',
'thumbnail',
'url'
]
def get_count_need(self, obj):
drink_ingredient_qs = obj.ingredients.all()
user = self.context['request'].user
user_qs = User.objects.filter(username=user.username)
if user_qs.exists() and user_qs.count() == 1:
user_obj = user_qs.first()
user_ingredient_qs = user_obj.ingredient_set.all()
return (user_ingredient_qs & drink_ingredient_qs).count()
return 0
型号:
class Drink(models.Model):
name = models.CharField(max_length = 1000, null=True, blank=True)
ingredients = models.ManyToManyField(Ingredient, blank=True)
user = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
class Ingredient(models.Model):
name = models.CharField(max_length = 1000)
ingredient_category = models.ForeignKey(Category, null=True, blank=True)
slug = models.SlugField(max_length=255, unique=True)
user = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True)
查看
class DrinkListAPIView(ListAPIView):
serializer_class = DrinkListModelSerializer
pagination_class = LargeResultsSetPagination
permission_classes = [AllowAny]
def get_queryset(self, *args, **kwargs):
user = self.request.user
qs = Drink.objects.all()
userQuery = self.request.GET.get('user')
query = self.request.GET.get("q")
filters = self.request.GET.getlist('filter')
if query:
qs = qs.filter(name__icontains=query)
elif filters:
qs = qs.filter(playlist__name__iexact=filters[0])
for filter in filters[1:]:
qs = qs | Drink.objects.filter(playlist__name__iexact=filter)
elif userQuery and user.is_authenticated():
qs = qs.filter(user=user)
return qs.order_by('-timestamp')
当前,我正在按时间戳对查询集进行排序,因为它位于自身的模型中,但是我需要通过 count_need订购它,它是序列化程序的一部分。我试图做类似 qs = qs.annotate(count_need = Count('ingredients'& user_ingredient_qs))。order_by(count_need)
的事情,但这显然由于'ingredients'而无效'只是一个字符串,而不是Drink的成分查询集。
Currently, I'm ordering the queryset by timestamp since it is in the model it self, but i need to order it by 'count_need' which is part of the serializer. I tried to do something like qs = qs.annotate(count_need=Count('ingredients' & user_ingredient_qs)).order_by(count_need)
but this clearly doesnt work since 'ingredients' is just a string here and not the Drink's ingredient queryset.
推荐答案
一种可行的方法是实现和自定义<列表序列化程序上的code> to_representation :
One way that might work well is to implement and customize to_representation
on the list serializer:
def to_representation(self, data):
iterable = data.all() if isinstance(data, models.Manager) else data
iterable = sorted(iterable, key=lambda x: x.count_need)
return [
self.child.to_representation(item) for item in iterable
]
这篇关于如何从序列化程序字段订购Django Rest Framework queryset?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!