2017-08-31 63 views
1

我有一個簡單的模型,其中User可以參與多個GameGame可以由多個User播放。每個UserGame中都有一個score字段。使用Django REST序列化與單個額外字段的多對多關係

爲了實現這一點,我按照Django文檔中提供了一種通過創建第三模型Membership連結的Game表和User一個來實現與一個附加的字段這種ManyToMany關係的例子。

我有以下models.py

from django.contrib.auth.models import AbstractUser 
from django.db.models.signals import post_save 
from django.dispatch import receiver 
from rest_framework.authtoken.models import Token 
from django.db import models 

class User(AbstractUser): 
    pass 

# triggered as soon as a new user is saved in the db 
@receiver(post_save, sender=User) 
def create_auth_token(sender, instance=None, created=False, **kwargs): 
    if created: 
     Token.objects.create(user=instance) 


class Game(models.Model): 
    users = models.ManyToManyField(User, through='Membership') 


class Membership(models.Model): 
    user = models.ForeignKey(User, on_delete=models.CASCADE) 
    game = models.ForeignKey(Game, on_delete=models.CASCADE) 
    score = models.IntegerField() 

然後我寫了serializers.py

from rest_framework import serializers 
from .models import User, Membership, Game 


class UserSerializer(serializers.ModelSerializer): 

    class Meta: 
     model = User 
     # unique email 
     model._meta.get_field('email').__dict__['_unique'] = True 
     fields = ('id', 'username', 'password', 'email') 

    def create(self, validated_data): 
     user = super().create(validated_data) 
     if 'password' in validated_data: 
       user.set_password(validated_data['password']) 
       user.save() 
     return user 

class GameSerializer(serializers.ModelSerializer): 

    users = UserSerializer(many=True) 

    class Meta: 
     model = Game 
     fields = ('users',) 

class MembershipSerializer(serializers.HyperlinkedModelSerializer): 

    id = serializers.ReadOnlyField(source='game.id') 

    class Meta: 
     model = Membership 

     fields = ('id', 'score') 

我的目標是能夠通過張貼像保存一個新的Game

{ 
{user_id = 1, 
score = 25}, 
{user_id = 2, 
score = 10} 
} 

我想知道如何達到t他的。

回答

0

要達到此目的,您可以使用Django通用視圖,您可以在其中創建CreateAPI視圖,其中每個遊戲之後都可以創建成員對象。

但是你必須使用ModelSerializer而不是HyperlinkedModelSerializer。

0

手動執行此操作爲:

serializers.py

class MembershipSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Membership 
     fields = ('user ', 'game', 'score') 

views.py

class GameViewSet(ModelViewSet): 
    queryset = Game.objects.all() 
    serializer_class = GameSerializer 
    permission_classes = (IsAuthenticated,) 

    @detail_route(methods=['POST']) 
    def bulk_create(self, request, pk): 
     game = self.get_object() 
     datas = request.data.getlist('data') 
     import ast 
     for _data in datas: 
      data = ast.literal_eval(_data) 
      data['game'] = game.id 
      serializer = MembershipSerializer(data=data) 
      if serializer.is_valid() 
       serializer.save() 
      else: 
       pass 
     return Response('success') 

您發佈的數據是一樣的東西{ '數據':[{USER_ID = 1 ,score = 25}]}

post url是/game/your_game_id/bulk_create/, not test cod e,你可能會遇到一些錯誤,但你可以這樣做。

相關問題