0

I understand what this error is saying, just not understanding how to pass user instance in a request(postman).

Following is my model.

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')

serializer.

class GameSerializer(serializers.HyperlinkedModelSerializer):

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

and viewset is

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

Till here "u'http://localhost:8000/players/1/'" works fine.
As soon as I do following .

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 

the same API call throws following error
ValueError: Cannot assign "u'http://localhost:8000/players/1/'": "Game.referee" must be a "User" instance.

Should I really create user instance from the url or there is more elegant way to pass the user instance?

Kishor Pawar
  • 3,386
  • 3
  • 28
  • 61
  • can you try like this? game = Game.objects.create( referee_id=request.data.get('referee', request.user),.... – rsb Jan 23 '18 at 09:42
  • @rsb, earlier (deleted) answers suggested that, but when I do that, it was throwing type casting issue. `_id` is expecting `int` whereas request parameter is `url string` – Kishor Pawar Jan 23 '18 at 09:46
  • parse as int(request.user) – rsb Jan 23 '18 at 09:49
  • 1
    no need to do that, as you can directly get the `id` like `request.user.id`. But for other fields like `player_1`, `player_2` etc, I wanted to use value from request only. See my answer below, that was inherited from django's own code. – Kishor Pawar Jan 23 '18 at 09:53

1 Answers1

0

So after inspecting the CreateModelMixin, I got an idea and I did the following.

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
Kishor Pawar
  • 3,386
  • 3
  • 28
  • 61