django rest 框架 PUT 返回 404 而不是创建对象

Max*_*ulo 5 django django-rest-framework

我希望能够使用相同的请求创建或更新对象。该操作应该是幂等的。

如果对象存在,则向 DRF 发送 PUT 请求按预期工作,但如果对象不存在,我会得到 404 而不是创建它。

模型.py:

class Btilog(models.Model):
    md5hash = models.CharField(primary_key=True, max_length=32)
    vteip = models.ForeignKey('vte.VTE')
    timestamp = models.DateTimeField(blank=False)
    source = models.TextField()
    code = models.CharField(max_length=10, blank=False)
    msg = models.TextField(blank=False)
Run Code Online (Sandbox Code Playgroud)

api.py:

class BtilogSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Btilog

class BtilogVSet(viewsets.ModelViewSet):
    queryset = models.Btilog.objects.all()
    serializer_class = BtilogSerializer
    permission_classes = (permissions.AllowAny,)
Run Code Online (Sandbox Code Playgroud)

网址.py:

...
router = routers.DefaultRouter()
router.register(r'btilog', api.BtilogVSet)

urlpatterns = patterns('',
    url(r'^api/', include(router.urls)),
    ...
)
Run Code Online (Sandbox Code Playgroud)

失败的请求

http --form PUT http://192.168.10.121:8888/logger/api/btilog/60c6b9e99c43c0bf4d8bc22d671169b1/ vteip='172.25.128.85' 'code'='Test' 'md5hash'='60c6b9e99c43c0bf4d8bc22d671169b1' 'timestamp'='2015-05-31T13:34:01' msg='Test' source='Test'
HTTP/1.0 404 NOT FOUND
Allow: GET, PUT, PATCH, DELETE, HEAD, OPTIONS
Content-Type: application/json
Date: Mon, 09 Feb 2015 15:16:47 GMT
Server: WSGIServer/0.1 Python/2.7.6
Vary: Accept, Cookie

{
    "detail": "Not found"
    }
Run Code Online (Sandbox Code Playgroud)

如此处所述:http : //restcookbook.com/HTTP%20Methods/put-vs-post/ put 的正确行为应该是创建不存在的对象。

使用 DRF 的可浏览 API 工具发出请求时会发生同样的错误。DRF 的行为也一样吗?我做错了什么?

Mat*_*tko 5

好吧,也许您应该尝试覆盖处理 PUT http 方法的模型视图集中的更新方法:

class BtilogVSet(viewsets.ModelViewSet):
    queryset = models.Btilog.objects.all()
    serializer_class = BtilogSerializer
    permission_classes = (permissions.AllowAny,)

    def update(self, request, *args, **kwargs):
        try:
            instance = Btilog.objects.get(pk=kwargs['pk'])
            serializer = serializers.BtilogSerializer(instance=instance,data=request.data)
            if serializer.is_valid():
                btilog=serializer.save()
                return Response(serializer.data,status=status.HTTP_200_OK)
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
        except Btilog.DoesNotExist:
            serializer = serializers.BtilogSerializer(data=request.data)
        if serializer.is_valid():
            btilog=serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Run Code Online (Sandbox Code Playgroud)