代码之家  ›  专栏  ›  技术社区  ›  Sethen xQbert

django rest框架发布需要字典

  •  0
  • Sethen xQbert  · 技术社区  · 7 年前

    我正试图将外键关系发布到我的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 回复  |  直到 7 年前
        1
  •  1
  •   JPG    7 年前

    从您的几条评论中,我了解到您需要在 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 实例

        2
  •  1
  •   Jason Havenaar    7 年前

    它将归结为您的字符序列化器和阶段序列化器。如果要输入1种格式(使用 serialisers.PrimaryKeyRelatedField() ),但输出另一个( CharacterSerializer , StageSerializer ),最好使用2个序列化器并在视图中切换。

    在您的视图中,您可以覆盖 get_serializer_class 并检查请求方法,或者在视图集的情况下,可以检查正在调用的方法。

        3
  •  0
  •   RishiG    7 年前

    当您使用另一个序列化程序声明与序列化程序相关的字段时,如下所示

    character = CharacterSerializer()
    

    你告诉django rest框架你想要一个嵌套的序列化器。你想要的是这样的东西

    character = serializers.PrimaryKeyRelatedField()
    

    或者您可以将显式字段声明保留在序列化程序之外(因为这是默认的),请参见 the doc on serializer relations .