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。 –