2017-08-31 61 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,你可能会遇到一些错误,但你可以这样做。

相关问题