如何使用Django Rest Fram处理外键

2024-09-26 18:07:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在努力使我的API工作,教程对这一部分相当棘手。我想要一个“/comments/”POST请求,body{movie_id:1,content=“Some comment”)并将其连接到某个电影。在

在序列化程序中我得到: {'movie': [ErrorDetail(string='This field is required.', code='required')]}

如何将电影标识映射到电影?顺便说一句,我可以把名字改成电影,如果这样比较容易的话。在

在模型.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')

在序列化程序.py公司名称:

^{pr2}$

在视图.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)

Tags: frompyimportdata电影modelsresponserequest
2条回答

嵌套数据的工作方式与我预期的稍有不同。在

如果要将评论连接到电影,则需要将电影对象传递给您的评论,而不是电影对象的主键。在

在幕后,Django会自动在你的comment对象上创建一个新的字段“movie_id”,其中存储了电影的主键,但是你不需要担心这个问题。所以我将注释中的字段称为“movie”,否则Django将创建一个新字段“movie_id_id”。在

我在序列化程序中定义了一个自定义的create方法,得到了类似的结果:

在序列化程序中:

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作为“movie”传递,而没有自定义的创建方法,也没有在序列化程序中定义“movie_id”?在

我想你可以这样做:

class CommentSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Comment
        fields = '__all__'

另外,related name用于反向关系。所以它会这样工作:

如果Comment模型有相关的名称comments,如下所示:

^{pr2}$

然后您可以像这样访问来自电影的评论:

for m in Movie.objects.all():
    m.comments.all()

相关问题 更多 >

    热门问题