Reputation: 37
I'm attempting to send a POST request from my frontend to add a new "Achievement" record. The achievement record has a foreign key field referring to a set, which contains many achievements. However, when I attempt to save, I get the error: "{"set": ["Incorrect type. Expected resource identifier object, received Set."]}" I don't know what a "resource identifier type" is and cannot find any docs on it by searching online. Here is my POST request data: {"achievement":{"title":"Rails is Omakase","description":"Lorem ipsum","experience":100,"set":"52"}}
I've tried setting "set" to the id of the set and the "Set" serializer instance before saving.
Serializers.py
class SetSerializer(serializers.ModelSerializer):
class Meta:
model = Set
fields = ('id', 'title', 'description')
class AchievementSerializer(serializers.ModelSerializer):
class Meta:
model = Achievement
fields = ('id', 'title', 'description', 'experience', 'set')
models.py
class Set(models.Model):
title = models.CharField(max_length=100, blank=False)
description = models.TextField()
class JSONAPIMeta:
resource_name = "sets"
class Achievement(models.Model):
title = models.CharField(max_length=100, blank=False)
description = models.TextField()
experience = models.IntegerField()
set = models.ForeignKey(Set, on_delete=models.CASCADE, related_name="achievements")
views.py
class AchievementList(APIView):
def post(self, request):
data = request.data["achievement"]
setId = data["set"]
set = Set.objects.get(pk=setId)
data["set"] = set
serializer = AchievementSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse({"achievement":serializer.data}, safe=False)
return JsonResponse(serializer.errors, status=400)
Upvotes: 0
Views: 465
Reputation: 37
I found a solution by reading some JSON docs: https://jsonapi.org/format/#document-resource-identifier-objects. The error stated that it wanted a resource identifier object passed in for the "set" key. A resource identifier object is simply an object that contains type and id members. Thus, I ensure that set had type and id elements and it solved the issue. Thus, my new post request looks like this: {"achievement":{"title":"Rails is Omakase","description":"Lorem ipsum","experience":100,"set":{"type":"sets","id":"4"}}}
Upvotes: 0
Reputation: 653
If you keep your post
to just this:
def post(self, request):
data = request.data["achievement"]
serializer = AchievementSerializer(data=data)
if serializer.is_valid():
serializer.save()
return JsonResponse({"achievement":serializer.data}, safe=False)
return JsonResponse(serializer.errors, status=400)
Then I had no issues running it. Generally, a primary key is expected for an object. I used the following test:
class TestAchievementList(TestCase):
def test_add_achievement(self):
title = 'title'
description = 'desc'
experience = 1
set_object = Set.objects.create(title='new set')
json = {
'achievement': {
'title': title,
'description': description,
'experience': experience,
'set': set_object.id
}
}
url = reverse('achievements')
response = self.client.post(url, data=json, content_type='application/json')
self.assertEqual(response.status_code, 200)
self.assertIn('achievement', response.json())
achievement_json = response.json()['achievement']
self.assertEqual(achievement_json['title'], title)
self.assertEqual(achievement_json['description'], description)
self.assertEqual(achievement_json['experience'], experience)
self.assertEqual(achievement_json['set'], set_object.id)
Upvotes: 1