Repository: django-tastypie/django-tastypie

Issue:
Strange "pk" field with PUT and with always_return_data
This simple procedure shows a strange "pk" field appearing only when updating (PUT) a resource:

Create:
```
$ curl -H 'Content-type: application/json' -X POST -d '{"field1":"value"}' http://127.0.0.1:8000/api/v1/model1/
{"field1": "value", "id": 1, "resource_uri": "/api/v1/model1/1/"}
```

Update (PUT):
```
$ curl -H 'Content-type: application/json' -X PUT -d '{"field1":"value"}' http://127.0.0.1:8000/api/v1/model1/1/
{"field1": "value", "id": 1, "pk": "1", "resource_uri": "/api/v1/model1/1/"}
```

Update (PATCH):
```
$ curl -H 'Content-type: application/json' -X PATCH -d '{"field1":"value"}' http://127.0.0.1:8000/api/v1/model1/1/
{"field1": "value", "id": 1, "resource_uri": "/api/v1/model1/1/"}
```

This causes unexpected behavior on my client, as it sees an unexpected field.


Discussion:

Resolving patch:
diff --git a/tastypie/resources.py b/tastypie/resources.py
--- a/tastypie/resources.py
+++ b/tastypie/resources.py
@@ -2256,6 +2256,11 @@ def lookup_kwargs_with_identifiers(self, bundle, kwargs):
         lookup parameters that can find them in the DB
         """
         lookup_kwargs = {}
+
+        # Handle detail_uri_name specially
+        if self._meta.detail_uri_name in kwargs:
+            lookup_kwargs[self._meta.detail_uri_name] = kwargs.pop(self._meta.detail_uri_name)
+
         bundle.obj = self.get_object_list(bundle.request).model()
         # Override data values, we rely on uri identifiers
         bundle.data.update(kwargs)
@@ -2265,10 +2270,6 @@ def lookup_kwargs_with_identifiers(self, bundle, kwargs):
         bundle = self.hydrate(bundle)
 
         for identifier in kwargs:
-            if identifier == self._meta.detail_uri_name:
-                lookup_kwargs[identifier] = kwargs[identifier]
-                continue
-
             field_object = self.fields[identifier]
 
             # Skip readonly or related fields.


Test patch:
diff --git a/tests/core/tests/resources.py b/tests/core/tests/resources.py
--- a/tests/core/tests/resources.py
+++ b/tests/core/tests/resources.py
@@ -2914,6 +2914,25 @@ def test_put_detail(self):
         new_note = Note.objects.get(slug='cat-is-back-again')
         self.assertEqual(new_note.author, author)
 
+    def test_put_detail_with_always_return(self):
+        # Check for issue #1576
+        resource = AlwaysDataNoteResource()
+        request = HttpRequest()
+        request.GET = {'format': 'json'}
+        resp = resource.get_detail(request, pk=1)
+        self.assertEqual(resp.status_code, 200)
+        resp = json.loads(resp.content.decode('utf-8'))
+
+        request = MockRequest()
+        request.GET = {'format': 'json'}
+        request.method = 'PUT'
+        request.set_body(json.dumps(resp))
+        putresp = resource.put_detail(request, pk=1)
+        self.assertEqual(putresp.status_code, 200)
+        data = json.loads(putresp.content.decode('utf-8'))
+
+        self.assertEqual(set(data.keys()), set(['title', 'slug', 'content', 'is_active', 'created', 'updated', 'id', 'resource_uri']))
+
     def test_put_detail_with_use_in(self):
         new_note = Note.objects.get(slug='another-post')
         new_note.author = User.objects.get(username='johndoe')