我正在 Django Rest Framework 中创建 API,但在多对多关系方面遇到问题。
我正在尝试创建一部电影并为其分配类型(电影和类型之间的多对多关系)。
这是我的模型:
class Genre(models.Model):
id = models.IntegerField(primary_key=True)
name = models.CharField(null=False,blank=False,max_length=50)
def __str__(self):
return self.name
class Movie(models.Model):
id = models.IntegerField(primary_key=True,null=False,blank=False)
adult = models.BooleanField(null=False,blank=False)
backdrop_path = models.CharField(null=True,blank=True,max_length=200)
budget = models.BigIntegerField (default=0)
homepage = models.CharField(null=True,blank=True,max_length=200)
original_language = models.CharField(max_length=10)
original_title = models.CharField(max_length=200)
overview = models.CharField(max_length=1000)
poster_path = models.CharField(null=True,blank=True,max_length=200)
release_date = models.DateField(null=True,blank=True,)
revenue = models.BigIntegerField (default=0)
runtime = models.IntegerField(null=True,blank=True)
status = models.CharField(max_length=50)
tagline = models.CharField(null=True,blank=True,max_length=100)
title = models.CharField(max_length=200)
genres = models.ManyToManyField(Genre,blank=True)
def __str__(self):
return self.title
这是我的序列化器:
class GenresSerializers(serializers.ModelSerializer):
class Meta:
model = Genre
fields = ['id','name']
def create(self,validated_data):
instance, _ = Genre.objects.get_or_create(**validated_data)
return instance
class MovieGenreSerializer(serializers.ModelSerializer):
class Meta:
model = Genre
fields = ['id']
def create(self, validated_data):
instance, _ = Genre.objects.get(**validated_data)
return instance
class MoviesSerializer(serializers.ModelSerializer):
genres = GenresSerializers(many= True)
class Meta:
model = Movie
fields = [ 'id', 'adult', 'backdrop_path', 'budget', 'homepage', 'original_language', 'original_title', 'overview', 'poster_path', 'release_date', 'revenue', 'runtime', 'status', 'tagline', 'title', 'genres'
]
# extra_kwargs = {'id': {'read_only': True}}
def create(self, validated_data):
genres_data = validated_data.pop('genres', [])
genresInstances = []
for genre in genres_data:
genresInstances.append(Genre.objects.get(pk = genre['id']))
movie = Movie.objects.create(**validated_data)
movie.genre.set(genresInstances)
return movie
和我的观点:
class MovieViewSet(viewsets.ModelViewSet):
queryset = Movie.objects.all()
serializer_class = MoviesSerializer
当我尝试使用此请求正文创建一部新电影时(我已经创建了类型):
{
"id": 425,
"adult": false,
"backdrop_path": "/kK5OeulwVDniPgjNOGHvzcORzdG.jpg",
"budget": 59000000,
"homepage": "http://www.iceagemovies.com/films/ice-age",
"original_language": "en",
"original_title": "Ice Age",
"overview": "With the impending ice age almost upon them, a mismatched trio of prehistoric critters – Manny the woolly mammoth, Diego the saber-toothed tiger and Sid the giant sloth – find an orphaned infant and decide to return it to its human parents. Along the way, the unlikely allies become friends but, when enemies attack, their quest takes on far nobler aims.",
"poster_path": "/stQoHvo0q6ZcEkji2Z1wlAxKnDq.jpg",
"release_date": "2002-03-10",
"revenue": 383257136,
"runtime": 81,
"status": "Released",
"tagline": "They came. They thawed. They conquered.",
"title": "Ice Age",
"genres": [
{
"id": 16
},
{
"id": 35
},
{
"id": 10751
},
{
"id": 12
}
]
}
它像这样返回:
{
"genres": [
{
"id": [
"genre with this id already exists."
]
},
{
"id": [
"genre with this id already exists."
]
},
{
"id": [
"genre with this id already exists."
]
},
{
"id": [
"genre with this id already exists."
]
}
]
}
SlugRelatedFieldSerializer
[drf-doc]:
class MoviesSerializer(serializers.ModelSerializer):
genres = serializers.SlugRelatedField(
many=True, queryset=Genre.objects.all(), slug_field='name'
)
class Meta:
model = Movie
fields = [
'id',
'adult',
'backdrop_path',
'budget',
'homepage',
'original_language',
'original_title',
'overview',
'poster_path',
'release_date',
'revenue',
'runtime',
'status',
'tagline',
'title',
'genres',
]
# extra_kwargs = {'id': {'read_only': True}}
# no create
您可以使用以下命令创建项目:
{
# …,
"genres": ["horror", "music", "musical"]
}