diff options
| author | Tom Christie | 2012-10-05 16:24:52 +0100 | 
|---|---|---|
| committer | Tom Christie | 2012-10-05 16:24:52 +0100 | 
| commit | 2533c2452b383771f80e6d40c93ae4a5ef6a8cf7 (patch) | |
| tree | 9bf467db0f43bd921270850cb7f664cededd9388 | |
| parent | 7218bcbadeac76a939e757bd0c4c336846548b51 (diff) | |
| download | django-rest-framework-2533c2452b383771f80e6d40c93ae4a5ef6a8cf7.tar.bz2 | |
Support PUT for create
| -rw-r--r-- | rest_framework/mixins.py | 27 | ||||
| -rw-r--r-- | rest_framework/tests/generics.py | 15 | 
2 files changed, 41 insertions, 1 deletions
| diff --git a/rest_framework/mixins.py b/rest_framework/mixins.py index e3c7cf03..46821f64 100644 --- a/rest_framework/mixins.py +++ b/rest_framework/mixins.py @@ -71,13 +71,38 @@ class UpdateModelMixin(object):      Should be mixed in with `SingleObjectBaseView`.      """      def update(self, request, *args, **kwargs): -        self.object = self.get_object() +        try: +            self.object = self.get_object() +        except Http404: +            self.object = None +          serializer = self.get_serializer(data=request.DATA, instance=self.object)          if serializer.is_valid(): +            if self.object is None: +                obj = serializer.object +                # TODO: Make ModelSerializers return regular instances, +                # not DeserializedObject +                if hasattr(obj, 'object'): +                    obj = obj.object +                self.update_urlconf_attributes(serializer.object.object)              self.object = serializer.save()              return Response(serializer.data)          return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) +    def update_urlconf_attributes(self, obj): +        """ +        When update (re)creates an object, we need to set any attributes that +        are tied to the URLconf. +        """ +        pk = self.kwargs.get(self.pk_url_kwarg, None) +        if pk: +            setattr(obj, 'pk', pk) + +        slug = self.kwargs.get(self.slug_url_kwarg, None) +        if slug: +            slug_field = self.get_slug_field() +            setattr(obj, slug_field, slug) +  class DestroyModelMixin(object):      """ diff --git a/rest_framework/tests/generics.py b/rest_framework/tests/generics.py index c0645d6e..2a6a0744 100644 --- a/rest_framework/tests/generics.py +++ b/rest_framework/tests/generics.py @@ -208,3 +208,18 @@ class TestInstanceView(TestCase):          self.assertEquals(response.data, {'id': 1, 'text': 'foobar'})          updated = self.objects.get(id=1)          self.assertEquals(updated.text, 'foobar') + +    def test_put_to_deleted_instance(self): +        """ +        PUT requests to RetrieveUpdateDestroyAPIView should create an object +        if it does not currently exist. +        """ +        self.objects.get(id=1).delete() +        content = {'text': 'foobar'} +        request = factory.put('/1', json.dumps(content), +                              content_type='application/json') +        response = self.view(request, pk=1).render() +        self.assertEquals(response.status_code, status.HTTP_200_OK) +        self.assertEquals(response.data, {'id': 1, 'text': 'foobar'}) +        updated = self.objects.get(id=1) +        self.assertEquals(updated.text, 'foobar') | 
