0
我有一些产品,其中用户可以将一些标记为他最喜欢的产品。Django Rest Framework:按用户依赖的字段排序
收藏夹被建模为用户配置文件和产品之间的多对多关系。
我现在想通过API调用获取产品,但是首先按照我的喜好来订购,其他的都是次要的。现在,这取决于当前的请求,我不能通过Product.objects.all().order_by(...)
来做到这一点,因为模型不知道当前用户,并且我知道现在通过序列化程序或ModelViewSet来告诉查询的方式。
我试图获得两个查询集,一个让所有的产品,一个从用户配置文件中ModelViewSet
所有收藏夹,这样的:
class ProductViewSet(viewsets.ModelViewSet):
serializer_class = ProductCreateSerializer
# ...
def get_queryset(self):
favorited_products = self.request.user.profile.favorites.all()
products = Product.objects.all()
queryset = favorited_products | products
return queryset
这并不工作,为实体留在这个顺序。但是这个视图返回了几百个实体,所以当我试图用return queryset[:30]
来限制查询集时,默认排序似乎就会接管。
我试图做什么,甚至很容易实现?有人已经解决了类似的问题吗?
这里是我的模型:
class Product(models.Model):
product_name = models.CharField(max_length=200)
# ...
def __unicode__(self):
return self.product_name
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
favorites = models.ManyToManyField(Product)
@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
if created:
Profile.objects.get_or_create(user=instance)
@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
instance.profile.save()
我的串行:
class FavoriteField(serializers.BooleanField):
def get_attribute(self, instance):
return self.context['request'].user.profile.favorites.filter(pk=instance.pk).exists()
class ProductSerializer(serializers.ModelSerializer):
favorite = FavoriteField()
def update(self, instance, validated_data):
instance = super().update(instance, validated_data)
is_favourite = validated_data.get('favorite') # can be None
if is_favourite is True:
self.context['request'].user.profile.favorites.add(instance)
elif is_favourite is False:
self.context['request'].user.profile.favorites.remove(instance)
return instance
伟大的解决方法!我想指出kwarg应该是'output_field' – wasabigeek
谢谢@wasabigeek。我也修好了kwarg。 –