Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-serializer

accessing 2 foreign key fields at the same time in django serializers


I have the following models in my django rest framework project. in this project there are products and they have producers and importers.

# models.py
class Product(models.Model):
    name = models.CharField(max_length=255)
    producer = models.ManyToManyField(Company, related_name='producer')
    importer = models.ManyToManyField(Company, related_name='importer')

class Company(models.Model):
    name = models.CharField(max_length=255)

I need to make an API which retrieves an instance of the "Company" model and gives me a list of the products they have produced and another list for the products that they have imported

Now I know to do this with only one manytomany field, I can do the following:

class CompanyRetrieveSerializer(serializers.ModelSerializer):
    class ProductSerializer(serializers.ModelSerializer):
        class Meta:
            model = Product
            fields = ('name',)
    
    product_set = ProductSerializer(read_only=True, many=True,)
    class Meta:
        model = Company
        fields = '__all__'

but since there are two fields in the product model that reference the company model, this doesn't work. Is there any way to fix this issue?


Solution

  • Tehe reason this does not work is because you specified related_name='producer': related_name is the name of the relation in reverse, so it makes not much sense to name this producer. You can rename the relations to:

    class Product(models.Model):
        name = models.CharField(max_length=255)
        producer = models.ManyToManyField(Company, related_name='produced_products')
        importer = models.ManyToManyField(Company, related_name='imported_products')

    then you can serialize the two relations with:

    class CompanyRetrieveSerializer(serializers.ModelSerializer):
        class ProductSerializer(serializers.ModelSerializer):
            class Meta:
                model = Product
                fields = ('name',)
        
        produced_products = ProductSerializer(read_only=True, many=True)
        imported_products = ProductSerializer(read_only=True, many=True)
        
        class Meta:
            model = Company
            fields = '__all__'