You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django及DRF中使用PUT方法创建对象(含指定ID无对象场景)

嘿,针对你这两个关于Django和DRF中PUT方法的问题,我来分享下实际项目里常用的解决方案:

1. 如何在Django框架中使用PUT方法创建对象

Django原生视图并没有默认把PUT方法和对象创建绑定(通常PUT用于更新),所以需要我们自定义视图逻辑来实现。这里分两种常见场景:

基于函数的视图实现

from django.http import JsonResponse
from .models import YourModel
import json

def create_or_update_view(request, pk=None):
    if request.method == "PUT":
        try:
            # 解析PUT请求的JSON数据
            request_data = json.loads(request.body)
            
            # 方案1:如果传入了pk,用update_or_create实现"存在则更新,不存在则创建"
            if pk:
                obj, created = YourModel.objects.update_or_create(
                    id=pk,
                    defaults=request_data
                )
                status_code = 201 if created else 200
                return JsonResponse(
                    {"id": obj.id, "status": "created" if created else "updated"},
                    status=status_code
                )
            # 方案2:不指定pk,直接通过PUT请求创建新对象
            else:
                obj = YourModel.objects.create(**request_data)
                return JsonResponse({"id": obj.id, "status": "created"}, status=201)
                
        except Exception as e:
            return JsonResponse({"error": str(e)}, status=400)

基于类的视图实现

from django.views import View
from django.http import JsonResponse
from .models import YourModel
import json

class PutCreateView(View):
    def put(self, request, pk=None):
        try:
            request_data = json.loads(request.body)
            if pk:
                obj, created = YourModel.objects.update_or_create(id=pk, defaults=request_data)
            else:
                obj = YourModel.objects.create(**request_data)
                created = True
            
            response_data = {"id": obj.id, **request_data}
            return JsonResponse(response_data, status=201 if created else 200)
            
        except Exception as e:
            return JsonResponse({"error": str(e)}, status=400)

核心思路就是手动解析PUT请求的body数据,然后调用Django的ORM方法(create或update_or_create)来完成对象创建。

2. 在Django Rest Framework中,当指定ID不存在对应对象时,如何使用PUT方法创建该ID对应的对象

DRF默认的UpdateAPIView或RetrieveUpdateAPIView在处理PUT请求时,如果指定的ID不存在,会直接返回404。要实现"不存在则创建"的逻辑,我们可以自定义视图来捕获异常,或者重写相关方法:

方法1:捕获DoesNotExist异常手动创建

from rest_framework import generics
from rest_framework.response import Response
from rest_framework import status
from .models import YourModel
from .serializers import YourModelSerializer

class UpsertModelView(generics.GenericAPIView):
    queryset = YourModel.objects.all()
    serializer_class = YourModelSerializer

    def put(self, request, *args, **kwargs):
        pk = kwargs.get("pk")
        try:
            # 尝试获取对象,存在则更新
            instance = self.get_object()
            serializer = self.get_serializer(instance, data=request.data)
            serializer.is_valid(raise_exception=True)
            self.perform_update(serializer)
            return Response(serializer.data, status=status.HTTP_200_OK)
        
        except YourModel.DoesNotExist:
            # 对象不存在时,用指定的ID创建新对象
            create_data = request.data.copy()
            create_data["id"] = pk  # 确保创建的对象ID为指定值
            serializer = self.get_serializer(data=create_data)
            serializer.is_valid(raise_exception=True)
            self.perform_create(serializer)
            return Response(serializer.data, status=status.HTTP_201_CREATED)

方法2:重写get_object方法实现自动创建

from rest_framework import generics
from .models import YourModel
from .serializers import YourModelSerializer

class UpsertModelView(generics.UpdateAPIView):
    queryset = YourModel.objects.all()
    serializer_class = YourModelSerializer

    def get_object(self):
        pk = self.kwargs.get("pk")
        # 不存在则自动创建,存在则返回现有对象
        obj, _ = YourModel.objects.get_or_create(id=pk)
        return obj

注意事项:

  • 你的序列化器需要允许id字段被写入:在YourModelSerializer中,不要将id设置为read_only=True,或者直接把id包含在fields列表中,否则无法在创建时指定ID。
  • 方法2会在ID不存在时创建一个空对象(如果请求数据为空),如果需要避免这种情况,可以在get_object或者perform_update里添加额外的校验逻辑。

内容的提问来源于stack exchange,提问作者Aashi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 23:59:06