Skip to content

remove ModelViewSet PUT/update() method? #614

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

Closed
n2ygk opened this issue May 1, 2019 · 1 comment · Fixed by #643
Closed

remove ModelViewSet PUT/update() method? #614

n2ygk opened this issue May 1, 2019 · 1 comment · Fixed by #643
Assignees

Comments

@n2ygk
Copy link
Contributor

n2ygk commented May 1, 2019

DJA uses DRF's viewsets.ModelViewset which includes both PUT (update()) and PATCH (partial_update()) methods. However, the JSONAPI spec only defines PATCH. DJA allows the PUT method. This becomes more apparent when using the new DRF openapi schema generator since it wants to document the PUT method. While DJA implements PUT identically to PATCH, it might be better to not expose this method as the PUT semantics defines a full replacement, which DJA's PUT does not do, since it's just implementing PATCH.

I'm not sure exactly where the PUT method gets defined but I think the change is to replace DRF's ModelViewSet with a DJA-specific version that replaces
DRF's mixins.UpdateModelMixin with one that doesn't define it.

class ModelViewSet(AutoPrefetchMixin,
PrefetchForIncludesHelperMixin,
RelatedMixin,
viewsets.ModelViewSet):

You can see this by doing an OPTIONS http://localhost:8000/blogs/1 as in this example:

{
    "data": {
        "name": "Blog Instance",
        "description": "",
        "renders": [
            "application/vnd.api+json",
            "text/html"
        ],
        "parses": [
            "application/vnd.api+json",
            "application/x-www-form-urlencoded",
            "multipart/form-data"
        ],
        "allowed_methods": [
            "GET",
            "PUT",
            "PATCH",
            "DELETE",
            "HEAD",
            "OPTIONS"
        ],
        "actions": {
            "PUT": {
                "name": {
                    "type": "String",
                    "required": true,
                    "read_only": false,
                    "write_only": false,
                    "label": "Name",
                    "max_length": 100
                },
                "tags": {
                    "type": "GenericField",
                    "relationship_type": "OneToMany",
                    "relationship_resource": "taggedItem",
                    "required": false,
                    "read_only": true,
                    "write_only": false,
                    "label": "Tags",
                    "child": {
                        "type": "Serializer",
                        "required": false,
                        "read_only": true,
                        "write_only": false,
                        "children": {
                            "tag": {
                                "type": "Slug",
                                "required": true,
                                "read_only": false,
                                "write_only": false,
                                "label": "Tag",
                                "max_length": 50
                            }
                        }
                    }
                },
                "copyright": {
                    "type": "GenericField",
                    "required": false,
                    "read_only": true,
                    "write_only": false,
                    "label": "Copyright"
                }
            }
        }
    }
}
@sliverc
Copy link
Member

sliverc commented May 2, 2019

I agree this is a bug as it doesn't follow the specification. Also see FAQ.

I haven't tested this but would it not work if we overwrite update and raise a AttributeError when partial in kwargs is False?

Something like this:

def update(self, request, *args, **kwargs):
  if not kwargs.get('partial', False):
    raise AttributeError()
  return super().update(self, request, *args, **kwargs)

Needs to be tested whether this works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants