У меня есть некоторые продукты, из которых пользователь может отметить некоторые из своих любимых продуктов.Django Rest Framework: порядок от пользователя зависит от поля
Избранные моделируются как отношение многих к многим между профилем пользователя и продуктом.
Теперь я хотел бы получить продукты через API-вызов, но сначала заказывал по избранным, а все остальное второй. Теперь, поскольку это зависит от текущего запроса, я не могу сделать это через Product.objects.all().order_by(...)
, так как модель не знает текущего пользователя, и теперь я знаю, как рассказать запрос через сериализатор или ModelViewSet.
Я пытался получить два querysets, один со всеми продуктами, один со всеми фаворитами из профиля пользователя в 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. –