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

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

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:

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

Views.py:

class HeroSerializer(serializers.ModelSerializer):
    class Meta:
        model = Hero
        fields = ['Hero_id', 'race', 'age', 'class_']
        extra_kwargs = {
                'race': {
                    'required': False,
                    'allow_null':True
                 },
                'age': {
                    'required': False,
                    'allow_null':True
                 },
                'class_': {
                    'required': False,
                    'allow_null':True
                 }
            }

def PATCH(request):
if request.method == "PATCH":
      stream = io.BytesIO(request.body)
      data = JSONParser().parse(stream)
      serializer = HeroSerializer(data=data["json"],partial=True)
      if serializer.is_valid():
            serializer.save()
            return JsonResponse(data,save=False)
      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 将尝试创建新对象:

@api_view
def PATCH(request):
  instance = Hero.objects.get(Hero_id=request.data["json"]["Hero_id"])
  serializer = HeroSerializer(instance, data=data["json"], partial=True)
  if serializer.is_valid():
        serializer.save()
        return JsonResponse(data)
  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:

@api_view 
def PATCH(request):
  instance = Hero.objects.get(Hero_id=request.data["json"]["Hero_id"])
  serializer = HeroSerializer(instance, data=data["json"], partial=True)
  if serializer.is_valid():
        serializer.save()
        return JsonResponse(data)
  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:

确定