我正在努力使我的API正常工作,这些教程对于这部分非常棘手。我想要一个带有正文{movie_id:1,content =“ Some comment”)的'/ comments /'POST请求,并将其连接到某些Movie。
在序列化器中,我得到:
{'movie': [ErrorDetail(string='This field is required.', code='required')]}
如何将movie_id映射到电影?顺便说一句,如果这样更容易,我可以将名称更改为电影。
Models.py:
from django.db import models
from django.utils import timezone
class Movie(models.Model):
title = models.CharField(max_length=200)
year = models.IntegerField()
class Comment(models.Model):
content = models.TextField(max_length=300)
publish_date = models.DateField(default=timezone.now())
movie = models.ForeignKey(Movie, on_delete=models.CASCADE, related_name='movie_id')
serializers.py:
class MovieSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Movie
fields = '__all__'
class CommentSerializer(serializers.HyperlinkedModelSerializer):
movie_id = serializers.PrimaryKeyRelatedField(many=False, read_only=True)
class Meta:
model = Comment
fields = '__all__'
views.py(对于注释,电影效果很好):
from .models import Movie, Comment
from rest_framework import viewsets, status
from rest_framework.response import Response
from .serializers import MovieSerializer, CommentSerializer
class CommentViewSet(viewsets.ModelViewSet):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
def create(self, request, *args, **kwargs):
serializer = CommentSerializer(data=request.data, context={'request': request})
if serializer.is_valid(raise_exception=True):
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
答案 0 :(得分:0)
我认为您可以尝试这样:
class CommentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Comment
fields = '__all__'
此外,相关名称用于反向关系。因此它将像这样工作:
如果Comment
模型具有related_name comments
,如下所示:
class Comment(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE, related_name='comments')
然后,您可以像这样访问电影中的评论:
for m in Movie.objects.all():
m.comments.all()
答案 1 :(得分:0)
嵌套数据的工作方式与我的预期有所不同。
如果要将注释连接到电影,则需要将电影对象传递到注释,而不是电影对象的主键。
在后台,Django会在您的注释对象上自动创建一个新字段'movie_id',该字段存储了电影的主键-但您不必为此担心。因此,我将注释中的字段称为“ movie”,否则Django将创建一个新字段“ movie_id_id”。
通过在序列化程序中定义自定义创建方法,我得到了与工作类似的东西:
在序列化器中:
class CommentSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Comment
fields = '__all__'
def create(self, validated_data):
themovieid = validated_data.pop('movie_id', None) # remove movie_id from the comment data
themovie = Movie.objects.get(pk=themovieid) # find the movie object
return Comment.objects.create(movie=themovie, **validated_data)
我已尝试将其调整为适合您的代码,希望它可以帮助您使其正常工作。我已经从序列化器中删除了movie_id:您的模型定义了所有需要的内容。
编辑:您是否尝试过在评论数据中简单地将电影的ID传递为“电影”,没有自定义创建方法,并且未在序列化程序中定义“电影ID”?