我有以下3个模型(第三个模型店不重要)。 有商店、产品和商品(哪个商店有哪些商品以及他们提供的价格)。
class Product(models.Model):
name=models.CharField(max_length=100)
class Shopitem(models.Model):
product = models.ForeignKey(Product, related_name='shopitems', on_delete=models.CASCADE)
price=models.IntegerField()
#shop field is not important to my question
shop = models.ForeignKey(Shop, related_name='shopitems', on_delete=models.CASCADE)
在我的 ProductSerializer 中,我为 ShopItemSerialzer 做了一个嵌套的序列化程序,效果很好。
但是我怎样才能得到所有产品的列表,这些产品是按商品价格过滤的?最重要的是,价格是一个查询参数,我将通过 GET 请求 127.0.0.1/?price=500.
在视图集中的 get_queryset() 中获取它类似的问题在 stackoverflow 上问了很多,但遗憾的是没有一个能为我解决。
我看到的一个解决方案是将这个函数添加到我的产品模型中,并从序列化程序中调用它:
class Product(models.Model):
name=models.CharField(max_length=100)
def some_function(self):
return ShopItem.objects.filter(product=self, price__gt=340)
class ProductSerializer(serializers.ModelSerializer):
shopitems=ShopItemSerializer(many=True, read_only=True,source="some_function")
这很好,但不是很好。我在价格上过滤的值 340 必须硬编码到该函数中。我如何将任何参数传递给它,我通过 self.request.query_params['price'] 得到这个 some_function?
我还看到了其他解决方案,它们覆盖了序列化程序中的 def to_representation(self, data):,但我对此感到非常困惑,不确定如何正确使用它。 其他帖子中显示的一些解决方案使用 .select_related() 或 prefetch_related,但我的产品模型不指向 ShopItem,但 ShopItem 指向 Product,我可以使用它来过滤 shopitems 价格并获取产品,但我的目标是使用 Product 视图集和 Product.objects.bla().bla().bla() ...并在这里以某种方式进行过滤。
有什么想法吗?
你可以在序列化器中使用
default
参数来传递你想要的查询集:
class Product(models.Model):
name = models.CharField(max_length=100)
class ShotItemsGraterThanPrice:
requires_context = True
def __call__(self, serializer_field):
return ShopItem.objects.filter(product=serializer_field.instance, price__gt=serializer_field.context['request'].query_params['price'])
class ProductSerializer(serializers.ModelSerializer):
shopitems = ShopItemSerializer(many=True, read_only=True, default= ShotItemsGraterThanPrice())
在视图中初始化它时不要忘记将请求传递给序列化程序:
serializer = ProductSerializer(context={'request': request})