caxefaizan
caxefaizan

Reputation: 321

I want to post a list of JSON values to a model's field in Django

I want to post a movie into the collection's movie field( list of movies). I define the model as

class Movie(models.Model):
    # collection = models.ForeignKey(Collection, on_delete = models.CASCADE) #, related_name='reviews'
    title = models.CharField(max_length=200)
    description = models.CharField(max_length=200)
    genres = models.CharField(max_length=200)
    uuid = models.CharField(max_length=200)
    def __str__(self):
        return self.title

class Collection(models.Model):
    title = models.CharField(max_length=200)
    uuid = models.CharField(max_length=200, primary_key = True)
    description = models.CharField(max_length=200)
    movie = models.ForeignKey(Movie, on_delete = models.CASCADE)

    def __str__(self): 
        return self.title

this is how i am using the viewset

class CollectionViewSet(viewsets.ModelViewSet):
    queryset = models.Collection.objects.all()
    serializer_class = serializers.CollectionSerializer

but i am not able to enter values for the movie field enter image description here

also my serializer

class CollectionSerializer(serializers.ModelSerializer):
     class Meta:
        model = Collection
        fields = '__all__'

Upvotes: 0

Views: 93

Answers (2)

Guillaume
Guillaume

Reputation: 2006

By default, DRF will represent the relationship with a PrimaryKeyRelatedField, thus expecting a movie ID.

To achieve what you want (create an instance of movie with a collection), you need to overwrite the foreign key field in your serializer with your own Movie serializer.

class MovieSerializer(serializers.ModelSerializer):
     class Meta:
        model = Movie
        fields = '__all__'

class CollectionSerializer(serializers.ModelSerializer):
     movie = MovieSerializer()
     class Meta:
        model = Collection
        fields = '__all__'

     def create(self, validated_data):
         movie = validated_data.pop('movie')
         movie = Movie .objects.create(**movie )
         collection = Collection.objects.create(movie=movie, **validated_data)
         return collection

You need to overwrite the create method so when creating a Collection, you also create a movie.

However, I am not sure the foreign key is set in the right model in your model. (a movie belongs to many collection but not the other way around?) If that's not what you want, just reverse the logic for the serializer.

Edit:

Sending the following should work fine:

{ "uuid": "1001",
  "title": "Action", 
  "description": "Action Movies",
  "movie": { "title": "The Burkittsville 7",
             "description": "The story of Rustin Parr.",
             "genres": "Horror",
             "uuid": "5e904"
            }
 } 

The only problem as I mentionned earlier is in your model you defined the foreign key field in collection. So it expects one single movie instance and not a list, thus I took off the brackets you put around movie. Maybe you should consider setting the foreign key in the Movie model, or use a Many to many relationship.

Upvotes: 1

dinesh bhupathi
dinesh bhupathi

Reputation: 1

#models.py
class Movie(models.Model):
    # collection = models.ForeignKey(Collection, on_delete = models.CASCADE) #, related_name='reviews'
    title = models.CharField(max_length=200)
    description = models.CharField(max_length=200)
    genres = models.CharField(max_length=200)
    uuid = models.CharField(max_length=200)
    def __str__(self):
        return self.title

class Collection(models.Model):
    title = models.CharField(max_length=200)
    uuid = models.CharField(max_length=200, primary_key = True)
    description = models.CharField(max_length=200)
    movie = models.ManyToManyField(Movie, on_delete = models.CASCADE)

    def __str__(self): 
        return self.title

serializers.py:
class MovieSerializer(serializers.ModelSerializer):
    class Meta:
        model = Movie
        fields = '__all__'
class CollectionSerializer(serializers.ModelSerializer):
    movie = MovieSerializer(read_only=True, many=True)

    class Meta:
        model = Collection
        fields = '__all__'

hope this will give you better unserstand this will work for you

Upvotes: 0

Related Questions