Skip to content
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

Views are using a subclass or HttpRequest #141

Closed
wants to merge 16 commits into from
Closed

Views are using a subclass or HttpRequest #141

wants to merge 16 commits into from

Conversation

sebpiq
Copy link
Contributor

@sebpiq sebpiq commented Jan 22, 2012

The new custom request takes care of ".DATA", ".FILES", overloaded HTTP method, content type and content.

  • tests
  • some doc.

@tomchristie
Copy link
Member

Nice one!
I assume there's some docs that we'd need to change to for, and that the examples would need altering too?
There's some stuff in there that I'll probably change slightly, but this looks really helpful.

@sebpiq
Copy link
Contributor Author

sebpiq commented Jan 23, 2012

I'll update the examples, and correct the wrong tests. Concerning the docs, I am not really sure where it should be updated. Ideas ?

Also, while I am at it, what would you change ?

@tomchristie
Copy link
Member

Rather than create a new class at runtime, subclassing from request, I'd instead store the original request object in ._request and delegate any getattr, setattr calls through to the original request object. Then you don't need the request factory stuff.

t.

On 23 Jan 2012, at 06:03, [email protected] wrote:

I'll update the examples, and correct the wrong tests. Concerning the docs, I am not really sure where it should be updated. Ideas ?

Also, while I am at it, what would you change ?


Reply to this email directly or view it on GitHub:
#141 (comment)

@sebpiq
Copy link
Contributor Author

sebpiq commented Jan 23, 2012

Yep ... that's one of the suggestions I listed here : #128

Like I said there - the solution you suggest feels like the most hackish to me, especially when you need to do a method overriding :

def my_method(self, bla):
    do_stuff()
    self.__getattribute__('my_method')(bla)
    do_more_stuff()

And if it's for doing that, subclassing HttpRequest makes actually no sense ; also you loose the original request class (which can be a WSGIRequest or smthg else ...).
It is also very prone to naughty bugs (I know for having tried this approach many times in other projects).

That said, if you still think it's the best solution ... let's go for it. But you should really weight the pros and cons. And do you really think it'll make for less hackish code ?

@tomchristie
Copy link
Member

Sorry I hadn't read through that yet. Yup those look like the 3 possibilities to me too.

For overriding existing methods you'd do...

def my_method(self, ...):
    ...
    self._request.my_method(...)
    ...

I'm fairly sure it'll be pretty nice and clean, but if there's any issues happy to rethink.

@tomchristie
Copy link
Member

Re. docs. in terms of this pull request I'm only really concerned with making sure that any examples that are in there at the moment are updated if they need to be.

@sebpiq
Copy link
Contributor Author

sebpiq commented Jan 23, 2012

Aw ... yeah, I don't know what I had in mind with that snippet !!! You're absolutely right. On the other hand ... is it just a matter of preference ? Or is there an actual difference between the two solutions ? Because, as it works like that ... if it's just for cosmetics, we can also change it later.

@sebpiq
Copy link
Contributor Author

sebpiq commented Jan 23, 2012

Yep ... I'll update the examples. What about the doc ?

@tomchristie
Copy link
Member

Just make sure there's nowhere in the docs that's broken I guess.

On 23 Jan 2012, at 09:44, [email protected] wrote:

Yep ... I'll update the examples. What about the doc ?


Reply to this email directly or view it on GitHub:
#141 (comment)

@sebpiq
Copy link
Contributor Author

sebpiq commented Jan 24, 2012

Examples didn't need any modification (or so it seemed). I checked, I didn't see any place where request was used directly, so it seems ok to me. Now, to the docs !

@tomchristie
Copy link
Member

self.CONTENT is used all over the place, which I think we can replace with request.DATA after this change.

@tomchristie
Copy link
Member

Er, with request.CONTENT I mean. I was jumping ahead a bit too much there.

@sebpiq
Copy link
Contributor Author

sebpiq commented Jan 24, 2012

Note that in this pull request I didn't touch to .CONTENT.
This is part of ResourceMixin at the moment, and contains the validated content ... should data validation be put in the request (I personally think it shouldn't) ?
Anyway, wherever .CONTENT ends-up, it's for the next step (I mean that I'll take care of it after .DATA is settled).

@sebpiq
Copy link
Contributor Author

sebpiq commented Jan 24, 2012

And some doc + example in the browsable API

@tomchristie
Copy link
Member

Looking good!
I'm considering deferring pulling this in until we've done the same for responses too (I might find the time to do that.),
and then very soon after that making the 0.4.0 release.
What do you think?

@sebpiq
Copy link
Contributor Author

sebpiq commented Jan 26, 2012

I think it sounds good !
About the example (how-to) I wrote, I got a sudden inspiration that since the framework should be (one day) entirely uncoupled, it would be great to have a small topical guide on each feature that can be used individually (that's why I wrote this "how-to integrate enhanced requests to your custom views"). What do you think about that ?

@sebpiq
Copy link
Contributor Author

sebpiq commented Feb 7, 2012

Ok @tomchristie . The responses are done too. Now would be a good time to review it, and maybe think of merging it to the trunk at last !!!

@tomchristie
Copy link
Member

Great! It might take a little while before it gets pulled in - it's such a big backwards-incompatible change that I'd like to really go through it well before it gets released.

There's a few bits & pieces that I'd tweak - How would you like my to tackle that? - Do you want me to review and you make the changes, or would you like me to go ahead and make 'em myself. (Aware that you've already put a lot of time into this, so don't want to ask too much!)

raise ErrorResponse(status.HTTP_404_NOT_FOUND,
{'detail': 'That page contains no results'})
raise ImmediateResponse(
content={'detail': 'That page contains no results'},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drop the content keyword arg.

@tomchristie
Copy link
Member

Looking good!
Am looking forward to the point where you can just return a Response from any regular Django view.

@sebpiq
Copy link
Contributor Author

sebpiq commented Feb 10, 2012

Ok ... I made the suggested fixes. It would be great now if you could pull - so I can get this nice change set off my hands :) I know there are still a bunch of stuff to do, but we can create tickets for those, so that anybody motivated can also do it. For example, the examples - and DocumentingRenderer - are a bit broken, and I don't have time to fix them now.

@sebpiq
Copy link
Contributor Author

sebpiq commented Feb 10, 2012

I would say - if you do pull - there's 4 stuff still to be done :

@tomchristie
Copy link
Member

Yo. Also see my notes on #8 re. request.auth and request.user.

Going to need to start documenting all this pretty soon.

The end goal is that we should end up with 5 very nicely decoupled areas:

  • request / parsers / authentication
  • response / renderers / serialization
  • view
  • validation
  • resources & resourceviews

@sebpiq
Copy link
Contributor Author

sebpiq commented Feb 10, 2012

Hmm you forget to mention a huge bit :

  • deserialization
  • validation

And that's part of the problems mentioned in #158.

It's going to be complicated mostly because Django folks have made the choice (bad choice imo), to put together deserialization and validation in forms. And we wanna use forms right !? But I'd really really like those 2 steps to be tweakable separately. And that'll require a lot of niftiness and creativity !!!

@sebpiq
Copy link
Contributor Author

sebpiq commented Feb 10, 2012

Also I'm not entirely convinced that more stuff should live with request/response. How will you ensure after that everything is uncoupled ? request/parsers and response/renderers make sense because renderers and parsers are useless alone, and response and request are useless alone. But that's not the case for serialization or authentication !!! I would say the parts should be :

  • request / parsers
  • authentication
  • deserialization
  • validation
  • resources
  • serialization
  • response / renderers

Because all of those are atomic bits that you might want to use separately

@tomchristie
Copy link
Member

Also I'm not entirely convinced that more stuff should live with request/response.

The auth stuff has to be part of the request, because we have to force request.user to use our flexible per-request authentication, rather than just Django's global authentication backend.

If we don't do that then we end up with both request.user and view.user which makes no sense.
Even if we renamed view.user it's still confusing, because there's no obvious reason to the end user why they shouldn't access request.user directly.

The serialization going onto the response let's three things happen:

  1. Drop this hack: https://github.com/sebpiq/django-rest-framework/blob/b33579a7a18c2cbc6e3789d4a7dc78c82fb0fe80/djangorestframework/views.py#L241
  2. You can throw any kind of object into a response and they'll render sensibly. (Rather than only supporting basic python types)
  3. We can be super awesome and have a TemplateResponse, which renders to html using the given template by default, but can also render to the json/the self describing api/xml/whatever. You'd be able to return either style of response from any regular view in Django, and it's possible to build your entire site which supports all of .html, .json and .api on any view.

I'd really really like those 2 steps to be tweakable separately.

I don't think we need to go into lots of detail about validation/deserialization right now, that's one for another day.

Have faith! ;-p

@tomchristie
Copy link
Member

NB. I'm more likely to be swayed that the serializers bit might not be needed, but I think the auth part definitely is.

@sebpiq
Copy link
Contributor Author

sebpiq commented Feb 10, 2012

If we don't do that then we end up with both request.user and view.user which makes no sense.

Absolutely right. In fact, I haven't really looked at the authentication part, so I trust you.
But then it is going to be quite challenging to come up with a good API to still keeps a good separation between the two. Because on one hand they need to be integrated, and on the other hand, what if you want to use only Request ?

I'm totally convinced by 3. !!! I was thinking about that yesterday actually : what if ??? I tried to render all my pages AND json API with the same view from drf ? And that kind of give an answer to it !!! Although now (introducing get_renderers) it is quite easy to achieve the same functionality. So I think, it really makes sense, but once again, it's going to be a challenge to come-up with a good API - and keep a low coupling.

So, yeah ... I keep faith !!!

@tomchristie
Copy link
Member

Ace!

@tomchristie
Copy link
Member

(And comments noted.)

@sebpiq
Copy link
Contributor Author

sebpiq commented Feb 11, 2012

So ... apart from all that, is there still anything holding you from pulling this in ? Should I fix anything else ?

@sebpiq
Copy link
Contributor Author

sebpiq commented Feb 14, 2012

there is still something I couldn't fix, cause it requires more thinking : #163

@tomchristie
Copy link
Member

Pulled into develop. :)

@sebpiq
Copy link
Contributor Author

sebpiq commented Feb 17, 2012

Yaaaay !!! :D

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

Successfully merging this pull request may close these issues.

3 participants