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
Easily add/validate etags. #32
Comments
Okay, I have an preliminary patch: schinckel@cc3a88e |
Very happy for feedback on this, though. |
Ok, so, initially what I wrote was this.... Cool, yeah I'd really love to see this in. Coupla thoughts - you should be able to just use View.add_header, rather than the View._ETAG that you currently have. Secondly, I'd like to see the @condition, @etag and @last_modified decorates can probably be pretty much a straight-up clone of https://github.com/django/django/blob/master/django/views/decorators/http.py, just replacing a couple of add_header and ErrorResponses |
But was looking into things a bit more... |
And perhaps this isn't quite the right way to go afterall... |
You can actually return HttpResponses from REST framework views, they just don't get all the usual content negotiation/serialization stuff applied. The So, what I'm thinking is, if we simply added Obv it'd be helpful if we documented that, but it might make more sense than having to replicate something that Django already does. What do you think? |
There may be one problem with using the django decorators: I'm not sure they'll work with methods, only bare functions. The decorator I wrote was heavily based on one I found via StackOverflow just for this case. That may not be the case, in which case this solution sounds superior. Having said that, I have been returning the return data style, as it is less boilerplate, and I'm usually only returning objects I want to serialize as json. We may be able to make it work with both ways. Another option may be a mixin that adds these to the View class. It also occurs to me that the django decorators may not do the right thing with respect to conditional PUT, POST and DELETE requests. Just submitted a patch to sinatra to fix that issue. |
Ignore the last bit: clearly I hadn't read the code properly. |
Actually there's a point there: those decorators might not work ATM on methods, since they've got the additional 'self' argument. I'll prob look into that and poss submit a ticket to Django, since they ought to work with CBVs too... |
Ah, okay - I see the @method_decorator now... https://docs.djangoproject.com/en/dev/topics/class-based-views/#decorating-class-based-views
|
I'm sure I looked in that document, but I didn't see that decorator! |
I tried to use the django decorator and the initial result was really strange, with information which should belong only in the views appearing in unrelated etag functions. After a few hours trying to make it a little better, I came up a solution which resolved my problems and seems general enough. What are your thoughts on this: https://bitbucket.org/vitormazzi/django-rest-framework/changeset/6f8de4500c6f |
Hoping to breath some new life into this issue now that we're on the 2.x releases. My thoughts here are mostly cobbled together from trying to add the functionality in a project and from reading this post so definitely still rough. I see two areas where DRF needs to consider ETags - usage in views and how to get the unique representation of an instance's version. ViewsGET
PUT, PATCH, DELETE
Then a more detailed check after retrieving the object to see if the request thinks it's looking at the right one:
Unique Representation of an Instance VersionI don't think the actual generation of an object's ETag should be DRF's problem. I've been testing using the epoch time of my object's I propose that DRF looks up We'll also need to enforce ETags are retrieved from objects as a string since we're comparing against a header and trying to interpret the type would be painful at best. Options
|
@ghickman - I'd like to see the behavior for determining ETags and LastModified look similar to the other pluggable classes. Ie. Have a something like:
Caching signatures ought to deal with both ETags and LastModified, and there's a two different things we want to provide for:
There'd be a
This'd allow a CacheLookupClass matching the implementation you've described, but also other variants. You could also apply multiple cache lookup classes, at different last modified granularity, for example, Does the pluggable class side of this sound reasonable to you? |
I hadn't thought about LastModified as I'm not using it in my current implementation but it definitely makes sense to include given it's purpose. The pluggable classes sounds like a great idea, especially if we include LastModified and ETag implementations as basic examples. I like the idea that the GET caching would be super easy to turn on by with minimal changes to a project. I'd prefer to split the etag and last_modified generation into two methods (of those names) that, as you suggested, return tl;dr yes the pluggable class side sounds reasonable and should give much greater flexibility. I'm happy to start writing the patch for this. |
Hello everyone. If you interested i've implemented different approach for etag support in my extensions library http://chibisov.github.io/drf-extensions/docs/ |
This one was milestoned as 3.3 on purpose as I would kind of like us to give some formal direction on this at some point. Not super-concerned if we do choose to leave this closed, but it has been on my internal roadmap. |
Unfortunately the default implementation and documentation on the Etag functionality in drf-extensions is simply wrong and dangerously buggy. It changes the Etag if the request changes, not if the response changes. Which is exactly what you want for server-side caching, and exactly what you don't want for an Etag. |
@mbox the best thing would be to open an issue about this on drf-extensions or if you think it's a DRF "core" issue open on here. Please note that a failing test would be a good start for us to look at the issue. |
@mbox @xordoquy |
thanks |
Just a note for the future readers - I've created small package to use conditional decorators from Django together with DRF. So if you are interested: |
Django has an awesome etag/condition/last_modified decorator. It doesn't work with the d-r-f class-based views, as you cannot decorate 'get' with them. Because get returns an object that is not an http response, there is no way to add the etag header to the response.
I would like to see a way to do this from within d-r-f. I'm thinking something along the lines of an overridable method on a resource, or a view (or a mixin) that can be used to generate the etag.
The other way of doing it in django is to use the middleware, but it cannot shortcut running the body of the view altogether like the decorator can.
The text was updated successfully, but these errors were encountered: