Mike_Wazowski
Mike_Wazowski

Reputation: 81

How to filter with ManyToMany field .?

Offer has multiple products. When I try to print the details of the selected products, it shows some errors

Model

class Products(models.Model):
    name = models.CharField(max_length=30)
    price = models.CharField(max_length=30)


class Offer(models.Model):
    offer = models.IntegerField(default=0)
    products = models.ManyToManyField(Publication)

Serializer

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Products
        fields = ['name', 'price']

class OfferSerializer(serializers.ModelSerializer):
    products_list = serializers.SerializerMethodField()

    class Meta:
        model = Offer
        fields = ['id', 'offer', 'products_list']
        read_only_fields = ['id']

    def get_products_list(self, instance):
            products_id = instance.products
            products = Products.objects.filter(id=products_id)

            return ProductSerializer(products, many=True).data

Error

TypeError: int() argument must be a string, a bytes-like object or a number, not 'ManyRelatedManager'

Upvotes: 2

Views: 101

Answers (2)

Phan Dinh
Phan Dinh

Reputation: 285

If you want to get all products of a offer, you just need to use ProductSerializer in OfferSerializer

class OfferSerializer(serializers.ModelSerializer):
    products_list = ProductSerializer(many=True)

By the way, query in SerializerMethodField is not good ideal, it will hit database request many time if you use serializer in list, you should try using Django Subquery expression in this case

Upvotes: 0

Sergey Pugach
Sergey Pugach

Reputation: 5669

You were trying to pass a ManyToManyManager to your filter instead of id value. You can get all products using all() method of your manager.

def get_products_list(self, instance):
    products = instance.products.all()  # <- this is the issue
    return ProductSerializer(products, many=True).data

Upvotes: 1

Related Questions