Replace PrimaryKeyRelatedField with another field
<p>I have models which consist in a <code>User</code> model and a <code>Present</code> one. A <code>User</code> can have multiple <code>Present</code> but a <code>Present</code> has a unique <code>User</code>:</p>

<p>My <code>models.py</code> is:</p>

<pre><code>from django.db import models
from django.contrib.auth.models import User

class Present(models.Model):
    name = models.CharField(max_length=15)
    price = models.FloatField()
    link = models.CharField(max_length=15)
    isAlreadyBought = models.BooleanField()
    user = models.ForeignKey(User, related_name='presents', on_delete=models.CASCADE)
</code></pre>

<p>My <code>serializers.py</code> are:</p>

<pre><code>from django.contrib.auth.models import User, Group
from rest_framework import serializers
from blog.models import Present, Location
from django.contrib.auth.models import User


class UserSerializer(serializers.ModelSerializer):

    presents = serializers.PrimaryKeyRelatedField(many=True, queryset=Present.objects.all(), required=False)

    class Meta:
        model = User
        fields = ('username', 'password', 'email', 'presents')

    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 PresentSerializer(serializers.ModelSerializer):

    user = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), read_only=False, many=False)

    class Meta:
        model = Present
        fields = ('name', 'link', 'price', 'isAlreadyBought', 'user')

    def create(self, validated_data):
        return Present.objects.create(**validated_data)
</code></pre>

<p>Currently, if I want to get the all the presents associate with a given User, I use the primary key (in <code>views.py</code>):</p>

<pre><code>class PresentsOfUser(viewsets.ModelViewSet):
    queryset = Present.objects.all().filter(user=33)
    serializer_class = PresentSerializer
</code></pre>

<p>However, I would rather use the <code>username</code> field of the <code>User</code> instead of the primary key.</p>

<p>I have tried using a <code>SlugRelatedField</code> but I am not sure this is the right way to achieve my goal:</p>

<pre><code>class PresentSerializer(serializers.ModelSerializer):

    user = serializers.SlugRelatedField(queryset=User.objects.all(), slug_field='username', read_only=False, many=False)

    class Meta:
        model = Present
        fields = ('name', 'link', 'price', 'isAlreadyBought', 'user')

    def create(self, validated_data):
        return Present.objects.create(**validated_data)
</code></pre>

<p>And with this modification, I now use the following <code>View</code> to get the user <code>'Marcel'</code> whose <code>id</code> is <code>33</code>:</p>

<pre><code>class PresentsOfUser(viewsets.ModelViewSet):
    queryset = Present.objects.all().filter(user='Marcel')
    serializer_class = PresentSerializer
</code></pre>

<p>But in this case, I get:</p>

<pre><code>ValueError: invalid literal for int() with base 10: 'Marcel'
</code></pre>

<p>But if I replace <code>user='Marcel'</code> by <code>user=33</code> (as previously), I get:</p>

<pre><code>[{"name":"Nintendo","link":"fake_link","price":50.8,"isAlreadyBought":true,"user":"Marcel"},{"name":"Gamecube","link":"fake_link","price":50.8,"isAlreadyBought":true,"user":"Marcel"}]
</code></pre>

<p>where the user field is now the <code>username</code> and not the user's <code>id</code>.</p>

<p>However, I do not understand why filtering with <code>user='Marcel'</code> fails...</p>