'Alternative for StringRelatedField
I am trying to get following user with their names instead of PrimaryKey, I tried to use StringRelatedField. It worked for GET request, but it does not allow to write. Could not find any alternatives for this. I want to get json result as this:
{
"id": 1,
"user": "admin",
"following": "user_1"
}
I assume instead of using StringRelatedField I should redefine create in serializers, am I right?
model.py
class Follow(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, related_name='follower'
)
following = models.ForeignKey(
User, on_delete=models.CASCADE, related_name='following'
)
class Meta:
constraints = [
models.UniqueConstraint(
fields=['user', 'following'],
name='unique_user_following'
)
]
def __str__(self) -> str:
return self.following
serializer.py
class FollowSerializer(serializers.ModelSerializer):
user = serializers.SlugField(
read_only=True,
default=serializers.CurrentUserDefault()
)
# following = serializers.StringRelatedField()
class Meta:
model = Follow
fields = ('id', 'user', 'following',)
validators = [
serializers.UniqueTogetherValidator(
queryset=Follow.objects.all(),
fields=('user', 'following',)
)
]
def validate_following(self, value):
if value == self.context.get('request').user:
raise serializers.ValidationError(
'You can not follow yourslef!'
)
return value
views.py
class FollowViewSet(viewsets.ModelViewSet):
serializer_class = FollowSerializer
def get_queryset(self):
new_queryset = Follow.objects.filter(user=self.request.user)
return new_queryset
def perform_create(self, serializer):
serializer.save(user=self.request.user)
Solution 1:[1]
A SlugRelatedField allows to also perform a lookup when writing and thus retrieve in this case the user with the given username.
You thus can implement this as:
from django.contrib.auth import get_user_model
class FollowSerializer(serializers.ModelSerializer):
user = serializers.SlugField(
read_only=True,
default=serializers.CurrentUserDefault()
)
following = serializers.SlugRelatedField(
slug_field='username',
queryset=get_user_model().objects.all()
)
class Meta:
model = Follow
fields = ('id', 'user', 'following',)
# …
# …
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL[Django-doc] to refer to the user model, than to use theUsermodel [Django-doc] directly. For more information you can see the referencing theUsermodel section of the documentation.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Willem Van Onsem |


