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