Как работать с внешними ключами с Django Rest Framework - PullRequest
0 голосов
/ 15 марта 2019

Я изо всех сил пытаюсь заставить мой API работать, учебники довольно хитры в этой части.Я хочу получить POST-запрос '/ comments /' с телом {movie_id: 1, content = "Some comment") и подключить его к некоторому фильму.

В сериализаторе я получаю: {'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__'

просмотров.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)

Ответы [ 2 ]

0 голосов
/ 17 марта 2019

Вложенные данные работают немного иначе, чем я ожидал.

Если вы хотите подключить комментарий к фильму, вам нужно передать объект фильма в ваш комментарий, а не первичный ключ объекта фильма.

Под капотом 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 из вашего сериализатора: ваша модель определяет все, что нужно.

Редактировать: вы пытались просто передать идентификатор фильма как 'movie' в ваших данных комментария, без специального метода создания и не определять'movie_id' в вашем сериализаторе?

0 голосов
/ 15 марта 2019

Я думаю, вы можете попробовать вот так:

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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...