Skip to content

remove disallowed PUT method. #643

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 8, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ any parts of the framework not mentioned in the documentation should generally b
* Don't swallow `filter[]` params when there are several
* Fix DeprecationWarning regarding collections.abc import in Python 3.7
* Allow OPTIONS request to be used on RelationshipView
* Avoid raising validation error for missing fields on a PATCH
request for polymorphic serializers
* Remove non-JSONAPI methods (PUT and TRACE) from ModelViewSet and RelationshipView.
This fix might be a **BREAKING CHANGE** if your clients are incorrectly using PUT instead of PATCH.
* Avoid validation error for missing fields on a PATCH request using polymorphic serializers

### Deprecated

Expand Down
2 changes: 1 addition & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ Possible values:
* underscore

Note: due to the way the inflector works `address_1` can camelize to `address1`
on output but it cannot convert `address1` back to `address_1` on POST or PUT. Keep
on output but it cannot convert `address1` back to `address_1` on POST or PATCH. Keep
this in mind when naming fields with numbers in them.


Expand Down
23 changes: 19 additions & 4 deletions example/tests/integration/test_polymorphism.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,27 +185,42 @@ def test_polymorphism_relations_update(single_company, research_project_factory,
"type": "researchProjects",
"id": research_project.pk
}
response = client.put(reverse("company-detail", kwargs={'pk': single_company.pk}),
data=content)
response = client.patch(reverse("company-detail", kwargs={'pk': single_company.pk}),
data=content)
assert response.status_code == 200
content = response.json()
assert content["data"]["relationships"]["currentProject"]["data"]["type"] == "researchProjects"
assert int(content["data"]["relationships"]["currentProject"]["data"]["id"]) == \
research_project.pk


def test_invalid_type_on_polymorphic_relation(single_company, research_project_factory, client):
def test_polymorphism_relations_put_405(single_company, research_project_factory, client):
response = client.get(reverse("company-detail", kwargs={'pk': single_company.pk}))
content = response.json()
assert content["data"]["relationships"]["currentProject"]["data"]["type"] == "artProjects"

research_project = research_project_factory()
content["data"]["relationships"]["currentProject"]["data"] = {
"type": "invalidProjects",
"type": "researchProjects",
"id": research_project.pk
}
response = client.put(reverse("company-detail", kwargs={'pk': single_company.pk}),
data=content)
assert response.status_code == 405


def test_invalid_type_on_polymorphic_relation(single_company, research_project_factory, client):
response = client.get(reverse("company-detail", kwargs={'pk': single_company.pk}))
content = response.json()
assert content["data"]["relationships"]["currentProject"]["data"]["type"] == "artProjects"

research_project = research_project_factory()
content["data"]["relationships"]["currentProject"]["data"] = {
"type": "invalidProjects",
"id": research_project.pk
}
response = client.patch(reverse("company-detail", kwargs={'pk': single_company.pk}),
data=content)
assert response.status_code == 409
content = response.json()
assert len(content["errors"]) == 1
Expand Down
5 changes: 2 additions & 3 deletions example/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import rest_framework.parsers
import rest_framework.renderers
from django_filters import rest_framework as filters
from rest_framework import viewsets
from rest_framework.filters import SearchFilter

import rest_framework_json_api.metadata
Expand Down Expand Up @@ -42,7 +41,7 @@ def get_object(self):
return super(BlogViewSet, self).get_object()


class DRFBlogViewSet(viewsets.ModelViewSet):
class DRFBlogViewSet(ModelViewSet):
queryset = Blog.objects.all()
serializer_class = BlogDRFSerializer
lookup_url_kwarg = 'entry_pk'
Expand Down Expand Up @@ -105,7 +104,7 @@ def get_object(self):
return super(EntryViewSet, self).get_object()


class DRFEntryViewSet(viewsets.ModelViewSet):
class DRFEntryViewSet(ModelViewSet):
queryset = Entry.objects.all()
serializer_class = EntryDRFSerializers
lookup_url_kwarg = 'entry_pk'
Expand Down
5 changes: 3 additions & 2 deletions rest_framework_json_api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,20 +243,21 @@ class ModelViewSet(AutoPrefetchMixin,
PreloadIncludesMixin,
RelatedMixin,
viewsets.ModelViewSet):
pass
http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']


class ReadOnlyModelViewSet(AutoPrefetchMixin,
RelatedMixin,
viewsets.ReadOnlyModelViewSet):
pass
http_method_names = ['get', 'head', 'options']


class RelationshipView(generics.GenericAPIView):
serializer_class = ResourceIdentifierObjectSerializer
self_link_view_name = None
related_link_view_name = None
field_name_mapping = {}
http_method_names = ['get', 'post', 'patch', 'delete', 'head', 'options']

def get_serializer_class(self):
if getattr(self, 'action', False) is None:
Expand Down