Reputation: 631
I am learning Django and trying to create a Game REST API using Django REST framework.I am not sure how to update the publisher field.Do I need to create another Serializer for my Publisher class and implement a save method?
I am using POSTMAN to send a PUT request and I am recieving this:
"publisher": [
"Incorrect type. Expected pk value, received unicode."
]
when I send a JSON request
{
"name": "Test",
"release_date": "1979-01-01",
"rating": 5,
"comment": "Terrible Game!",
"publisher": "Me"
}
models.py
class Publisher(models.Model):
name = models.CharField(max_length=100)
def __unicode__(self):
return self.name
class Game(models.Model):
name = models.CharField(max_length=100)
release_date = models.DateField(null=True, blank=True)
rating = models.IntegerField(
null=True, blank=True,
validators=[MinValueValidator(0), MaxValueValidator(5)])
comment = models.TextField(null=True, blank=True)
publisher = models.ForeignKey(Publisher, null=True, blank=True)
def __unicode__(self):
return self.name
class Meta:
ordering = ('name',)
serializers.py
from rest_framework import serializers
from game.models import Game, Publisher
class GameSerializer(serializers.ModelSerializer):
publisher = serializers.PrimaryKeyRelatedField(allow_null=True, queryset=Publisher.objects.all(), required=False)
class Meta:
model = Game
fields = ('pk','name', 'release_date', 'rating', 'comment', 'publisher')
def create(self, validated_data):
"""
Create and return a new 'Game' instance, given the validated data.
"""
return Game.objects.create(**validated_data)
def update(self, instance, validated_data):
"""
Update and return an existing 'Game' instance, given the validated data.
"""
instance.name = validated_data.get('name', instance.name)
instance.release_date = validated_data.get('release_date',instance.release_date)
instance.rating = validated_data.get('rating', instance.rating)
instance.comment = validated_data.get('comment', instance.comment)
instance.publisher = validated_data.get('publisher', instance.publisher)
instance.save()
return instance
views.py
class GameDetail(APIView):
"""
Retrieve, update or delete a game instance.
"""
def get_object(self,pk):
try:
return Game.objects.get(pk=pk)
except Game.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
game = self.get_object(pk)
serializer = GameSerializer(game)
return Response(serializer.data)
def put(self, request, pk, format=None):
game = self.get_object(pk)
serializer = GameSerializer(game, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request, pk, format=None):
game = self.get_object(pk)
game.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
Upvotes: 1
Views: 761
Reputation: 672
You're sending a string ("Me") as the publisher attribute. That's why you get your "Incorrect type. Expected pk value, received unicode."
error.
Since publisher
is a ForeignKey
in your Game
model, you'll have to get the instance of "Me" Publisher
before saving it in your database.
One possible approach is to modify your update()
method in your serializer and search for the right instance :
instance.publisher = Publisher.objects.get_or_create(name=validated_data.get('publisher'))and then call
instance.save()
.
Upvotes: 1