Django остальные рамки размещения ожидает словарь - PullRequest
0 голосов
/ 08 июня 2018

Я пытаюсь опубликовать в своем API отношения с внешним ключом.Это возвращает меня назад, сообщая, что он ожидает словарь, а не int для character, character_opponent и stage.Это потому, что так настроены мои модели.У них есть отношения с иностранными ключами.Рассматриваемая модель выглядит следующим образом:

import uuid
from django.db import models
from django.utils import timezone
from analysis.models import Analysis
from characters.models import Character
from stages.models import Stage

class Match(models.Model):
    analysis = models.ForeignKey(Analysis, on_delete=models.CASCADE)
    character = models.ForeignKey(Character, on_delete=models.CASCADE, related_name='character')
    character_won = models.BooleanField()
    character_opponent = models.ForeignKey(Character, on_delete=models.CASCADE, related_name='character_opponent')
    character_opponent_won = models.BooleanField()
    created_at = models.DateTimeField(editable=False)
    id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    updated_at = models.DateTimeField(editable=False)
    stage = models.ForeignKey(Stage, on_delete=models.CASCADE)

    def __str__(self): 
        return '%s vs. %s on %s' % (self.character, self.character_opponent, self.stage)

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.created_at:
            self.created_at = timezone.now()
        self.updated_at = timezone.now()
        return super(Match, self).save(*args, **kwargs)

    class Meta:
        db_table = "matches"

А вот мой сериализатор:

from rest_framework import serializers
from matches.models import Match
from characters.serializers import CharacterSerializer
from stages.serializers import StageSerializer

class MatchSerializer(serializers.ModelSerializer):
    character = CharacterSerializer()
    character_opponent = CharacterSerializer()
    stage = StageSerializer()

    class Meta:
        model = Match
        fields = ('id', 'analysis', 'character', 'character_won', 'character_opponent', 'character_opponent_won', 'stage')

Есть ли какая-то опция, которую я здесь упускаю, чтобы иметь возможность правильно разместить сообщение?Ясно, что мне не нужно передавать весь объект персонажа каждый раз, когда я хочу что-то опубликовать, верно?Я должен быть в состоянии передать первичный ключ.

Ответы [ 3 ]

0 голосов
/ 08 июня 2018

Это будет зависеть от вашего CharacterSerializer и StageSerializer.Если вы хотите ввести 1 формат (используя serialisers.PrimaryKeyRelatedField()), но вывести другой (CharacterSerializer, StageSerializer), вам лучше всего использовать 2 сериализатора и переключаться на ваш взгляд.

На ваш взглядВы можете переопределить get_serializer_class и проверить свой метод запроса, или в случае набора представлений вы можете проверить вызываемый метод.

0 голосов
/ 08 июня 2018

Из ваших нескольких комментариев я понял, что вам нужен вложенный сериализатор в методе GET.Я предлагаю использовать два [или более] сериализатора для вашего класса API.
Если вы используете ModelViewSet Используется класс API, то вы можете переопределить метод get_serializer_class(), как показано ниже,

from rest_framework.viewsets import ModelViewSet


class MatchAPI(ModelViewSet):
    queryset = Match.objects.all()

    def get_serializer_class(self):
        if self.action == 'create':
            return MatchCreateSerializer
        return MatchSerializer

И ваш MatchCreateSerializer будет таким,

class MatchCreateSerializer(serializers.ModelSerializer):
    class Meta:
        fields = '__all__'
        model = Match

Таким образом, вам нужно только указать PKs из analysis, character и т. Д. При созданииMatch экземпляр

0 голосов
/ 08 июня 2018

Когда вы объявляете связанное с сериализатором поле с помощью другого сериализатора, например,

character = CharacterSerializer()

, вы сообщаете django-rest-framework, что вам нужен вложенный сериализатор.Вместо этого вам нужно что-то вроде этого

character = serializers.PrimaryKeyRelatedField()

или вы можете просто оставить явное объявление поля вне сериализатора (так как это по умолчанию), см. документация по отношениям сериализатора .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...