【问题标题】:ValueError: Cannot assign "u'http://localhost:8000/players/1/'": "Game.referee" must be a "User" instanceValueError:无法分配“u'http://localhost:8000/players/1/'”:“Game.referee”必须是“User”实例
【发布时间】:2018-06-30 07:27:05
【问题描述】:

我明白这个错误在说什么,只是不明白如何在请求中传递用户实例(邮递员)。

以下是我的模型。

class Game(models.Model):
    referee = models.ForeignKey(User, on_delete=models.CASCADE, related_name='referee')
    player_1 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='opponent_1')
    player_2 = models.ForeignKey(User, on_delete=models.CASCADE, related_name='opponent_2')
    attacker = models.ForeignKey(User, on_delete=models.CASCADE, related_name='attacker')
    status = models.CharField(max_length=20, choices=GAME_STATUS, default='QUEUED')
    game_type = models.CharField(max_length=20, choices=GAME_TYPE, default='LEAGUE')

序列化器。

class GameSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Game
        fields = ('__all__')

而视图集是

class GameViewSet(viewsets.ModelViewSet):
    queryset = Game.objects.all()
    serializer_class = GameSerializer

直到这里 "u'http://localhost:8000/players/1/'" 工作正常。
只要我关注。

def create(self, request):
    game = Game.objects.create(
        referee = request.data.get('referee', request.user),
        player_1 = request.data.get('player_1', None),
        player_2 = request.data.get('player_2', None),
        attacker = request.data.get('attacker', None),
        status = request.data.get('status', None),
        game_type = request.data.get('game_type', None)
        )
    game.save()
    return game 

相同的 API 调用引发以下错误
ValueError: Cannot assign "u'http://localhost:8000/players/1/'": "Game.referee" must be a "User" instance.

我真的应该从 url 创建用户实例还是有更优雅的方式来传递用户实例?

【问题讨论】:

  • 你可以这样试试吗? game = Game.objects.create(referee_id=request.data.get('referee', request.user),....
  • @rsb,较早的(已删除)答案建议这样做,但是当我这样做时,它会引发类型转换问题。 _id 期待 int 而请求参数是 url string
  • 解析为 int(request.user)
  • 不需要这样做,因为您可以像request.user.id一样直接获取id。但对于player_1player_2 等其他字段,我只想使用请求中的值。请参阅下面的答案,这是从 django 自己的代码继承的。

标签: python django django-rest-framework django-rest-viewsets


【解决方案1】:

所以在检查了CreateModelMixin 之后,我有了一个想法,我做了以下事情。

def create(self, request):
    serializer = self.get_serializer(data=request.data)

    # just to be cautious 
    serializer.is_valid(raise_exception=True)

    # actually converts urls to instances
    data = serializer.validated_data

    print data 
    # OrderedDict([(u'status', u'QUEUED'), (u'game_type', u'LEAGUE'), (u'referee', <User: kishor>), (u'player_1', <User: joey>), (u'player_2', <User: nick>), (u'attacker', <User: joey>)])

    # I can access model fields like below.
    print data["referee"].username

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 2019-11-14
    • 2020-04-04
    相关资源
    最近更新 更多