Fixed #29750 -- Added View.setup() hook.#10427
Conversation
carltongibson
left a comment
There was a problem hiding this comment.
Hi @francoisfreitag. Thanks for this.
Looks OK. (Still not sure it's quite to my taste but whatever... 🙂)
Yes, I think a doc example is worthwhile. Yes, in the topic page.
The example you give in the description is nice. Except I was surprised to see you still override dispatch() in ImpersonationWithMessageMixin. Obviously that works but I thought the idea here was to allow us to leave dispatch alone? Would it not work equally implementing init() and calling super()? (With correct MRO mixins could rely on attributes being set this way — it'd potentially get tricky but it's up to each to keep their code clean and it's already an "Advanced Topic".)
docs/ref/class-based-views/base.txt
Outdated
There was a problem hiding this comment.
Do we need a note here saying that you must call super() if overriding? (Or similar... obviously you could do it by hand...)
django/views/generic/base.py
Outdated
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
|
Hi Carlton, Thank you very much for reviewing the PR and your input.
In my mind,
Not exactly, the idea is to provide parent views and mixins with a way to abstract logic from child classes, but let children control the response that's generated. Maybe adding a message is not the best example, the example could be updated to check permissions. For example, we could return a In the ticket, I had hopes to move all |
I'd be super -1 on this. The |
5a7c1be to
57533c0
Compare
carltongibson
left a comment
There was a problem hiding this comment.
- I'm still not sure I like the feature. It's fine as implemented though.
- I'm a bit worried about the docs example. I think it will encourage people down bad roads, rather than being a hook for that time when you really do need it.
What do others think? (I know you like it @jdufresne 😀)
Yeah, I do like it and I think François has done a great job here. I'm +1 on merging this once the docs meet your approval. |
My only concern here is the |
|
I'm not too picky on the name. If |
|
My concern isn’t really the feature at this point. I wouldn’t go this way, but it’s fine and I can see the utility if it’s the style you want to use. So 👍 there. I am concerned about the docs example: I think a lot of users take the docs as being normative, as saying do this!; I think unless you really know what you’re doing putting parts of your view logic in dispatch is not something you should do. (You should just keep it in your view function, even if that means a bit of repetition calling If no one else is feeling this then I’m happy to let it pass. (It’s quite possible I’m just too old. 🙂) But that’s why I asked for other opinions (because I can’t shake the feeling, having given it time enough for a change of heart.) Happy to merge it, happy to release it, but I’d basically like to recuse myself on making the decision here. Thanks for your help all. |
57533c0 to
8a31de5
Compare
|
Many thanks @carltongibson for approaching this PR with such an open mind! I removed the example from topics and added a few lines in the If there's still doubt around this feature, I am happy to open a discussion on the mailing list. The previous discussion did not reach a consensus and other community members may have different perspective on this hook. I could post the removed example on the mailing list to describe the use case and gather opinions. What do you think? |
8a31de5 to
769a761
Compare
|
As for the name, I kept
|
|
Hi @francoisfreitag Thanks for the follow-up. I don't know that we need to go to the mailing list. Jon like feature, Simon has expressed support, I see the use of it (even if it's not my thing per se) — let's go with it. Only thing now is the docs. (And maybe a rename.) I like the changes you've made: they're much more in line with how I'd present it. Allow me to give it another once-over and we'll see about getting it in. Thanks for effort! |
francoisfreitag
left a comment
There was a problem hiding this comment.
Edits look good to me, thank you.
In the end, we won't provide use cases to explain the feature. Maybe we should add the use case for user impersonation suggested in a previous version of this PR to the ticket? That may help future readers understand the use case. What do you think?
|
My thought was that it's fine as-is, i.e. minus the example. (I think people looking for it can come up with their own use-cases.) There's plenty of discussion on the ticket (I think). I also thought that your use-case would make a good blog-post, on your own or company blog. (No harming in throwing a link to such on the ticket...) |
So I was just about to mark this RFC when I remembered this. Naming things... |
4cb1243 to
9f7f476
Compare
9f7f476 to
0df04c7
Compare
django/views/generic/base.py
Outdated
There was a problem hiding this comment.
I think if not hasattr(...) and raising an exception would be more in line with Django's style.
django/views/generic/base.py
Outdated
There was a problem hiding this comment.
You can omit the tuple and just put this on the previous line.
docs/ref/class-based-views/base.txt
Outdated
docs/ref/class-based-views/base.txt
Outdated
There was a problem hiding this comment.
a, b, and c (missing comma after 'b')
also missing .. versionadded:: 2.2 annotation
Also you mentioned a use case in the release notes but not here.
docs/releases/2.2.txt
Outdated
There was a problem hiding this comment.
I think "The new" is more inline with other notes.
View.init <django.views.generic.base.View.init> would render "View" also which would help.
docs/releases/2.2.txt
Outdated
There was a problem hiding this comment.
I would replace "class..." with "view" (no link)
docs/releases/2.2.txt
Outdated
tests/generic_views/test_base.py
Outdated
There was a problem hiding this comment.
Use self.assertRaisesMessage.
tests/generic_views/test_base.py
Outdated
There was a problem hiding this comment.
I would put this in the one test they're used in unless you think they have potential to be used in future tests.
|
Hey Tim. Thanks for the review. Do you have any thoughts on the naming question? |
|
No strong opinion. One idea is that it the name |
OK, let's call that a +0.5 🙂 I'll say the same for Simon and myself (for total +1.5) @francoisfreitag Could you change for Simon's suggestion of Then if you could address Tim's review comments and rebase I think we're there. 🎉 |
|
I don't mind changing to |
0df04c7 to
3a377bd
Compare
|
Early commit to address comment "Use Ready for review. |
3a377bd to
53d05c3
Compare
c1022f4 to
0af6de3
Compare
|
Sorry @timgraham, I push-forced your edits. I restored them from https://github.com/django/django/compare/53d05c3d166eb2f5e410b7a6c2c947a6480b1c50..c1022f47e051924288d2d5cfbdf7c7cfecd59a79, but would not mind a second set of eyes. I'll make sure to use |
0af6de3 to
8b3dfa3
Compare
|
The commit message was reverted. I was only able to restore the first line. |
|
Note: I did make a change on my side ( |
carltongibson
left a comment
There was a problem hiding this comment.
OK. This looks ready to go. Thanks for the effort @francoisfreitag! 🎁
Just the one observation...
docs/ref/class-based-views/base.txt
Outdated
There was a problem hiding this comment.
I preferred the shorter version we had earlier:
Initializes view instance attributes: ``self.request``, ``self.args``
and ``self.kwargs`` prior to :meth:`dispatch`. Child classes overriding
this method must call ``super()``.
There was a problem hiding this comment.
I restored it from https://github.com/django/django/compare/53d05c3d166eb2f5e410b7a6c2c947a6480b1c50..c1022f47e051924288d2d5cfbdf7c7cfecd59a79#diff-2df22e647d63040c7db3eca921c888fdL87, I believe this change was part of @timgraham's cosmetic edits.
The longer version explains the purpose of this hook, that's why I have a small preference for it.
8b3dfa3 to
e671337
Compare
…n docs. Backport of 734fde7 from master
| def test_not_calling_parent_setup_error(self): | ||
| class TestView(View): | ||
| def setup(self, request, *args, **kwargs): | ||
| pass # Not calling supre().setup() |
Allows encapsulating logic in View mixins for reuse in child classes.
The standard request processing cycle is:
Before
init(), it was not possible to reuse self attributes set in parent views and mixins from the concrete view, because calling the parent method generates aHttpResponse.https://code.djangoproject.com/ticket/29750