1

我试图让我的头周围如何应对django-rest-framework(DRF)中的嵌套模型。我读过this part of the documentation,它涉及编写一个可以保存嵌套对象的序列化程序,但它不完全是我想要的。在一篇文章中,我有相关(多对多)对象的ID。如何创建一个对象从链接到嵌套对象从邮政编码

例如:
可以说我有一场比赛(认为足球,网球),比赛是在两支球队之间进行的,而球队由球员组成。我想发送一个POST与比赛信息和player-id。如果球员之前已经打过一支球队,否则我们应该组队。

如果玩家1打4场比赛对球员2,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') 
+0

我想'team2'访问后的数据应该包含player2 ID? – Sayse

+0

@Sayse id是每个团队的成员,本身并不是这样:从这个最小化的例子中不清楚,但它被定义为第二个团队的第一个玩家(所以如果团队有2个玩家,那么你会得到一个玩家2以及)。这就是为什么在这个帖子里有两个player-id-1的原因。每个团队一个:) – Nanne

+0

好吧,是的,这是有道理的。我不确定我现在有足够的时间来提供一个完整的答案,但是你可能会发现'def create(self,request)'方法更容易处理,因为基本上你会做很多相同的工作就好像它是一个django视图 - 允许你使用'get_or_create'等 – Sayse

回答

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 

这是否工作,为您的需求?最好的方法是在串行器中解决这类问题,即将它们转换为合适的对象/字段。

这就是说,如果你想要做简单的东西,总有self.request您可以在ModelViewSet

+0

因此我创建了一个使用此序列化器的特定端点('ModelViewSet'),并处理这里的所有逻辑。听起来不错。我被挂在了用于我的模型的序列化器上,但显然不需要这样。好点子。 – Nanne

+0

虽然小问题:'ModelViewSet'似乎基于一个特定的模型,在这种情况下并不是真的,对吧?我只有序列化器和视图。我应该定义哪种视图让我发布?没有其他需要我想在这一点上? – Nanne