'Trying To Retrieve Name Instead of Primary Key, But Django Rest Framework complains of Value Error. If I try to fix it, I got other errors too
My Models:
def upload_to(instance, filename):
return 'images/{filename}'.format(filename=filename)
class StreamPlatform(models.Model):
name = models.CharField(max_length=200)
about = models.TextField(max_length=2000)
website = models.URLField(max_length=2500)
def __str__(self):
return self.name
class WatchList(models.Model):
title = models.CharField(max_length=250)
image = models.ImageField(_('Image'), upload_to=upload_to, default='images/default.jpg')
storyline = models.TextField(max_length=2000)
platform = models.ForeignKey(StreamPlatform, on_delete=models.CASCADE, related_name='watchlist')
active = models.BooleanField(default=True)
avg_rating = models.FloatField(default=0)
number_rating = models.IntegerField(default=0)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
My Serializers:
class WatchListSerializer(serializers.ModelSerializer):
platform = serializers.CharField(source='platform.name')
class Meta:
model = WatchList
fields = '__all__'
extra_kwargs = {'avg_rating': {'read_only': True}, 'number_rating': {'read_only': True}}
def create(self, validated_data):
return WatchList.objects.create(**validated_data)
class StreamPlatformSerializer(serializers.ModelSerializer):
watchlist = WatchListSerializer(many=True, read_only=True)
class Meta:
model = StreamPlatform
fields = '__all__'
My View:
class WatchListAV(generics.ListCreateAPIView):
permission_classes = [AdminOrReadOnly]
parser_classes = [MultiPartParser, FormParser]
queryset = WatchList.objects.all()
serializer_class = WatchListSerializer
pagination_class = WatchListLimitOffsetPagination
filter_backends = [filters.SearchFilter, filters.OrderingFilter]
search_fields = ['title', 'platform__name']
ordering_fields = ['avg_rating']
The issue I got is that Django Rest Framework complains in PostMan that:
ValueError at /watch/list/ Cannot assign "{'name': '8'}": "WatchList.platform" must be a "StreamPlatform" instance.
When I try to fix it like this in the WatchListSerializer:
platform = serializers.PrimaryKeyRelatedField(queryset = StreamPlatform.objects.all(), source='platform.name',)
I got a new error instead:
ValueError at /watch/list/ Cannot assign "{'name': <StreamPlatform: Blah>}": "WatchList.platform" must be a "StreamPlatform" instance.
When I commented out the error-prone code bits, I got the correct Response, just not the Response I'm hoping for.
{
"id": 26,
"title": "Awesome Show Blah Blah",
"image": "http://127.0.0.1:8000/media/images/default.jpg",
"storyline": "Any blah...",
"active": true,
"avg_rating": 0.0,
"number_rating": 0,
"created": "2022-05-12T17:04:04.151048Z",
"platform": 8
}
I'm hoping for the "platform": 8 to be shown in name like "platform": Blah. So how do you fix this?
Solution 1:[1]
You can use the SlugRelatedField
.
class WatchListSerializer(serializers.ModelSerializer):
platform = serializers.SlugRelatedField(many=True, queryset=StreamPlatform.objects.all(), slug_field='name')
class Meta:
model = WatchList
fields = ['platform', 'all_other_fields']
extra_kwargs = {
'avg_rating': {'read_only': True},
'number_rating': {'read_only': True}
}
def create(self, validated_data):
return WatchList.objects.create(**validated_data)
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 |