如何从序列化器字段订购 Django Rest Framework 查询集?

2024-05-08

我如何订购 DjangoQuerySet来自序列化器字段?由于字段太复杂,我无法订购QuerySet using annotate我也无法将值存储在模型中。

Edit:

串行器

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

Models:

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)

View

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)但这显然不起作用,因为“成分”在这里只是一个字符串,而不是饮料的成分查询集。


一种可能有效的方法是实施和定制to_representation在列表序列化器上:

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
    ]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从序列化器字段订购 Django Rest Framework 查询集? 的相关文章

随机推荐