簡體   English   中英

如何使用Django Rest Framework處理外鍵

[英]How to handle foreign keys with Django Rest Framework

我正在努力使我的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(對於Comment,Movie工作正常):

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)

我想你可以嘗試這樣:

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()

嵌套數據的工作方式與我的預期有所不同。

如果要將注釋連接到電影,則需要將電影對象傳遞到注釋,而不是電影對象的主鍵。

在幕后,Django會自動在評論對象上創建一個新的字段“movie_id”,其中存儲了電影的主鍵 - 但您無需擔心這一點。 所以我會在評論'電影'中調用該字段,否則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”?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM