如何在POST中创建一个带有id的嵌套对象链接的对象

时间:2017-01-16 20:28:46

标签: python django django-models django-views django-rest-framework

我正试图了解如何应对django-rest-framework(DRF)中的嵌套模型。我已阅读this part of the documentation,它涉及编写可以保存嵌套对象的序列化程序,但这并不是我想要的。在帖子中,我有相关(多对多)对象的id。

例:
让我们说我有一场比赛(想想足球,网球),两场比赛之间有一场比赛,球队由球员组成。我想发送一个POST的match-info和player-id。如果球员在已经有球队之前已经参赛,否则我们应该组建球队。

如果玩家1对玩家2玩第4场游戏,则POST看起来像

team_1[player_1_id]:1  // 1st player of team 1 is user 1
team_2[player_1_id]:2  // 1st player of team 2 is user 2
game:4

事实上需要完成所有类型的事情我认为view可能是一个好地方:我需要在准备好连续编码器之前对一些数据进行随机播放;但是我该如何开始?

我可以覆盖perform_create来做魔术:

class MatchViewSet(viewsets.ModelViewSet):
  queryset = Match.objects.all()
  serializer_class = MatchSerializer

  def perform_create(self, serializer):
    // get the user ids form the post
    // find if there is are teams, otherwise create the teams
    // get team ids from above
    // add team ids to data so serializer kan save
    serializer.save()

所以我需要找出

  • 如何从帖子中获取ID
  • 如何获得合适的团队ID(并可能首先创建它们)
  • 如何在序列化器上传递它们。

具体来说,通过使用DRF和/或ModelViewSet的就地功能可以完成这些功能。我也试图在这里学习框架:)

模型看起来像这样。我不打算保存完整的嵌套对象,所以我认为我不需要在这里添加特定的create

class Match(models.Model):
  game = models.ForeignKey(Game)
  teams = ManyToManyField(Team, through='MatchTeams')

可能相关的其他模型是;

class MatchTeams(models.Model):
  match = models.ForeignKey(Match)
  team = models.ForeignKey(Team)

class Team(models.Model):
  name = models.TextField(max_length=128)
  users = ManyToManyField(User, through='TeamUsers')

1 个答案:

答案 0 :(得分:2)

我认为你应该制作一个特殊的序列化器: http://www.django-rest-framework.org/api-guide/serializers/#saving-instances

这样的事情:

class MatchSerializer(serializers.Serializer):
    player_1 = serializers.IntegerField()
    player_2 = serializers.IntegerField()
    id = serializers.IntegerField()

    def create(self, validated_data):
        try:
            team = Team.objects.filter(Q(users__id=player_1 & users__id=player_2))
        except Team.DoesNotExcist:
            team = Team.objects.create()
            team.users.add(player_1)
            team.users.add(player_2)
            team.save()
        match = super(serializers.Serializer, self)
        match.teams.add(team)
        # Something like this, but you have to post both team members at once. Can be made so you don't have to oc. You also might want to check the count of teams before adding them :-)
        return match

    def update(self, instance, validated_data):
        # same as create but on a given match?
        return instance

这是否适合您的需求?最好的方法是在Serializers中解决这类问题,这就是它们的用途,将请求字段转换为适当的对象/字段。

也就是说,如果你想做一些简单的事情,你可以在self.request

中访问ModelViewSet {