how to filter on a field from another Model in nested Serializer

Viewed 157

I have the following 3 models (third model Shop not important). There are shops, products, and shopitems (which shop has which item and at which price they offer it).

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)

In my ProductSerializer, I made a nested serializer to ShopItemSerialzer, which works great.

But how can I get list of all products, which are filtered by the shopitem price? And most importantly, the price is a query parameter, which I will get in my get_queryset() in the viewset, with the GET request 127.0.0.1/?price=500.

Similar questions are asked a lot on stackoverflow, but none of them sadly didn't solve it for me.

One solution I saw was to add this function to my Product model, and call it from the serializer:

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")

And this works good, but not great. The value 340 that I filter on the price must be hard coded into that function. How can I pass any parameter to it, that I get with self.request.query_params['price'], to this some_function?

I also saw other solutions, that override the def to_representation(self, data): in the serializer, but I am very confused by it, not sure how to use it correctly. Some solutions shown in other posts use .select_related() or prefetch_related, but my Product Model doesn't point towards ShopItem, but ShopItem points towards Product, which I can use to filter on shopitems price, and get the products, but my goal is to use the Product viewset, and Product.objects.bla().bla().bla() ... and do the filtering somehow here.

Any ideas?

0 Answers
Related