How do you create a Django Rest Framework serializer with many to many field?

139 views Asked by At

I have a model(Project) that contains ManyToManyField to another model(Screenshot). I want to create a view inheriting CreateAPIView such that it is able to serialize data for creating an instance of project model including the Screenshot model from the same view.

models.py

class Screenshot(models.Model):
    image = models.ImageField(default='screenshots.jpg',upload_to='screenshots')


class Project(models.Model):
    team=models.ForeignKey(Team,on_delete=models.CASCADE)
    name=models.CharField(max_length=100,null=True,blank=True)
    theme = models.ForeignKey(Theme,on_delete=models.CASCADE,null=True,blank=True)
    desc=models.TextField()
    accepted = models.BooleanField(default=False)
    git_url=models.URLField(null=True,blank=True)
    youtube_url=models.URLField(null=True,blank=True)
    screenshots=models.ManyToManyField(Screenshot)

serializers.py

class ScreenshotCreateSerializer(serializers.ModelSerializer):
    class Meta:
        model = Screenshot
        fields=['image']   


class ProjectCreateSerializer(serializers.ModelSerializer):
    image_1 = ScreenshotCreateSerializer()
    image_2 = ScreenshotCreateSerializer()
    image_3 = ScreenshotCreateSerializer()
    image_4 = ScreenshotCreateSerializer()
    image_5 = ScreenshotCreateSerializer()

    class Meta:
        model = Project
        fields = ['name','theme','desc','git_url','youtube_url','image_1','image_2','image_3','image_4','image_5']

    def create(self,validated_data):
        try:
            image1 = validated_data.pop('image_1')
            image2 = validated_data.pop('image_2')
            image3 = validated_data.pop('image_3')
            image4 = validated_data.pop('image_4')
            image5 = validated_data.pop('image_5')
        except:
            pass
        print(validated_data)
        test_team_obj = Team.objects.all()[0]
        project_obj = Project(**validated_data)
        project_obj.team = test_team_obj
        project_obj.save()

        if (image1):
            project_obj.screenshots.create(image=image1.get('image'))
        if (image2):
            project_obj.screenshots.create(image=image2.get('image'))
        if (image3):
            project_obj.screenshots.create(image=image3.get('image'))
        if (image3):
            project_obj.screenshots.create(image=image4.get('image'))
        if (image4):
            project_obj.screenshots.create(image=image5.get('image'))

        return project_obj

The form is displayed as expected with 5 image fields. After submitting the form, the required project instance is created, screenshot instances are created as well and the just created screenshot instances are linked to that just created project instance. Everything runs well. But an error arises saying:

Got AttributeError when attempting to get a value for field image_1 on serializer ProjectCreateSerializer. The serializer field might be named incorrectly and not match any attribute or key on the Project instance. Original exception text was: 'Project' object has no attribute 'image_1'.

Regardless of the error, the data is well updated on the database as desired. But the error is what killing me! I even tried to use a single image field instead of 5 and put many=True but it says:

Lists are not currently supported in HTML input

0

There are 0 answers