如何正确使用ModelSerializer进行补丁操作?

huangapple go评论104阅读模式
英文:

How to properly patch with ModelSerializer?

问题

  1. 如何根据 Hero_id 更新数据库中的特定行?
  2. 我该如何传递请求数据?我总是收到错误消息 'WSGIRequest' object has no attribute 'data'。
  3. 在我的情况下,JSONParser().parse(io.BytesIO(request.body))request.data 之间有什么区别?

以下是你要求的翻译内容:

  1. 如何根据 Hero_id 更新数据库中的特定行?
  2. 我该如何传递请求数据?我总是收到错误消息 'WSGIRequest' object has no attribute 'data'。
  3. 在我的情况下,JSONParser().parse(io.BytesIO(request.body))request.data 之间有什么区别?
英文:

I'm trying to .save() my data in database. But I get an error {'Hero_id':[ErrorDetail<string='Hero with this Hero_id already exists.',='unique'>]}.
Models.py:

  1. class Hero(models.Model):
  2. Hero_id = models.IntegerField(auto_created=True, primary_key=True, serialize=False, verbose_name='Hero_id')
  3. race = models.CharField(max_length=50, blank=True)
  4. age = models.IntegerField(blank=True)
  5. class_= models.CharField(max_length=50, blank=True)

Views.py:

  1. class HeroSerializer(serializers.ModelSerializer):
  2. class Meta:
  3. model = Hero
  4. fields = ['Hero_id', 'race', 'age', 'class_']
  5. extra_kwargs = {
  6. 'race': {
  7. 'required': False,
  8. 'allow_null':True
  9. },
  10. 'age': {
  11. 'required': False,
  12. 'allow_null':True
  13. },
  14. 'class_': {
  15. 'required': False,
  16. 'allow_null':True
  17. }
  18. }
  19. def PATCH(request):
  20. if request.method == "PATCH":
  21. stream = io.BytesIO(request.body)
  22. data = JSONParser().parse(stream)
  23. serializer = HeroSerializer(data=data["json"],partial=True)
  24. if serializer.is_valid():
  25. serializer.save()
  26. return JsonResponse(data,save=False)
  27. return JsonResponse(serializer.errors)

My incoming data is always containing Hero_id.
Example: {"json":{"Hero_id":"4", "race":"orc"}} or {"json":{"Hero_id":"4", "race":"Human", "age":"34", "class_":"archer"}}
Questions:
1)How to patch specific row in database depending on Hero_id?
2)How can I pass a request.data? I always get an error 'WSGIRequest' object has no attribute 'data'.
3)Is there any difference between JSONParser().parse(io.BytesIO(request.body)) and request.data in my case?

答案1

得分: 2

你需要将更新的实例传递给序列化器。如果没有它,Django 将尝试创建新对象:

  1. @api_view
  2. def PATCH(request):
  3. instance = Hero.objects.get(Hero_id=request.data["json"]["Hero_id"])
  4. serializer = HeroSerializer(instance, data=data["json"], partial=True)
  5. if serializer.is_valid():
  6. serializer.save()
  7. return JsonResponse(data)
  8. return JsonResponse(serializer.errors)

顺便说一下,你可以使用 api_view 装饰器来启用 Django REST 框架的请求处理。在这种情况下,你不需要手动解析请求体。

英文:

You need to pass updating instance to serializer. Without it, djnago will try to create new object:

  1. @api_view
  2. def PATCH(request):
  3. instance = Hero.objects.get(Hero_id=request.data["json"]["Hero_id"])
  4. serializer = HeroSerializer(instance, data=data["json"], partial=True)
  5. if serializer.is_valid():
  6. serializer.save()
  7. return JsonResponse(data)
  8. return JsonResponse(serializer.errors)

BTW you can use api_view decorator to enable Django rest framework request. In this case you don't need to parse request body manually.

huangapple
  • 本文由 发表于 2020年1月3日 23:11:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/59580955.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定