2017-04-06 38 views
0

我有一个序列化程序,适用于GET,POST,DELETE操作。它公开了我想要的模型字段。但是,对于PUT操作,用户将发回未构建到我的模型中的值,并且服务器将处理如何在模型上执行更新。我可以使用Postman或Curl发回数据,但它的工作原理是,但可浏览的API仍然如下所示:enter image description here如何将字段添加到不在我的模型中的django-rest-framework序列化程序?

对于PUT方法,我希望“is_winner”,“num_hands_won”和“score”实际的模型领域。我该怎么做呢? (让我知道在评论,如果你需要更多的信息)

StatisticsSerializer:

class StatisticsSerializer(serializers.ModelSerializer): 
    # pk = serializers.IntegerField(required=False) 
    class Meta: 
     model = Statistics 
     fields = [ 
      'url', 
      'games_won', 
      'hands_won', 
      'games_played', 
      'high_score', 
      'low_score', 
     ] 

统计型号:

class Statistics(models.Model): 
    # Define model fields: 
    user = models.OneToOneField(User, primary_key=True) 
    games_won = models.IntegerField(null=True, blank=True) 
    hands_won = models.IntegerField(null=True, blank=True) 
    games_played = models.IntegerField(null=True, blank=True) 
    high_score = models.IntegerField(null=True, blank=True) 
    low_score = models.IntegerField(null=True, blank=True) 

    def __str__(self): 
     return str(self.pk) 

    def increment_games_won(self, is_winner): 
     if is_winner is True: 
      self.games_won = self.games_won + 1 
     return self.games_won 

    def add_to_hands_won(self, num_hands_won): 
     if num_hands_won > 0 and num_hands_won < 8: 
      self.hands_won = self.hands_won + num_hands_won 
     return self.hands_won 

    def increment_games_played(self): 
     self.games_played = self.games_played + 1 
     return self.games_played 

    def new_high_score(self, score): 
     if score > self.high_score: 
      self.high_score = score 
     return self.high_score 

    def new_low_score(self, score): 
     if score < self.low_score: 
      self.low_score = score 
     return self.low_score 

统计视图集:

class StatisticsViewSet(DefaultsMixin, viewsets.ModelViewSet): 
    queryset = Statistics.objects.all() 
    serializer_class = StatisticsSerializer 
    filter_class = StatisticsFilter 
    search_fields = ('pk', 'user') 
    ordering_fields = ('games_won', 'hands_won', 'games_played', 'high_score', 'low_score') 

    def update(self, request, pk=None): 
     stats = self.get_object() 

     stats.increment_games_won(request.data['is_winner']) 
     stats.add_to_hands_won(request.data['num_hands_won']) 
     stats.increment_games_played() 
     stats.new_low_score(request.data['score']) 
     stats.new_high_score(request.data['score']) 
     stats.save() 

     serialized_stats = StatisticsSerializer(stats, context={'request': request}).data 
     return Response(serialized_stats) 
+0

为什么你需要它在可浏览的API上? – creimers

+0

我不知道。它使得API在开发过程中更容易使用。 – FlashBanistan

+0

我明白了。我看到它的方式,可浏览的API基于自动生成(模型)表单。您可以深入了解其他框架源代码,并了解如何自定义它,但这可能不值得付出努力......对于开发,我会推荐测试。 – creimers

回答

0

你也许可以使用其他串行,并用它为你PUT API
StatisticsUpdateSerializer:

class StatisticsUpdateSerializer: 
    is_winner = ... 
    num_hands_won = ... 
    score = ... 

及认沽API中使用串行或创建如图中提到的例子一条新路线DRF文档here

@detail_route(methods=['post']) 
def set_password(self, request, pk=None): 
    user = self.get_object() 

    // Use your serializer below 
    serializer = PasswordSerializer(data=request.data) 

    if serializer.is_valid(): 
     user.set_password(serializer.data['password']) 
     user.save() 
     return Response({'status': 'password set'}) 
    else: 
     return Response(serializer.errors, 
         status=status.HTTP_400_BAD_REQUEST) 
+0

根据我的理解,不能将字段添加到不在模型中的序列化程序。 – FlashBanistan