> > If the mixins are the way to go, it should be reflected in the doc more > (especially in the introduction doc).
If you want to make a PR with concrete edits, sure. Yes the example walks you through applying login_required as a decorator, but it does also say: These examples use login_required, however, the same behavior can be > obtained by using LoginRequiredMixin. > So it's at least there. On Thu, Feb 10, 2022 at 8:57 AM Martin Milon <martin.mi...@ensc.fr> wrote: > The introduction doc to class based view > https://docs.djangoproject.com/en/4.0/topics/class-based-views/intro/ > seems to prefer decorators, as it only illustrates the decorator side of > things with code blocks, and doesn't illustrate mixins at all. > If the mixins are the way to go, it should be reflected in the doc more > (especially in the introduction doc). > > about the > ``` > @method_decorator(some_decorator, name='dispatch') > class MyView(...): > ``` > way of doing things, i guess i just missed it, i would prefer a > cbv_decorator(some_decorator) > ``` > def cbv_decorator(func): > return method_decorator(func, name='dispatch') > ``` > but it's good enough like that. > > My team will switch to mixins, as it's a much more efficient way of doing > things that i also completely missed, thanks for bringing it up to me. > > Should we update the doc? I think the "using mixins" tab should have > similar code block exemples to what we can find in the "Decorating > class-based view" > Le mercredi 9 février 2022 à 20:45:13 UTC+1, Adam Johnson a écrit : > >> Additionally, it's always possible to apply decorators to CBV's like this: >> >> class MyView(...): >> ... >> >> my_view = some_decorator(MyView.as_view()) >> >> Then use my_view in your urls.py. This works because as_view() returns >> the "real view" function. >> >> ...and you can use method_decorator like this: >> >> @method_decorator(some_decorator, name='dispatch') >> class MyView(...): >> ... >> >> I think you then don't have to define a local dispatch in this case - the >> super version will be copied and wrapped. >> >> On Wed, Feb 9, 2022 at 7:30 PM Albert <al...@interia.eu> wrote: >> >>> Hi, >>> >>> For class based views there are mixins, LoginRequiredMixin, >>> PermissionRequiredMixin which give the same functionality. >>> >>> https://docs.djangoproject.com/en/4.0/topics/auth/default/#the-loginrequired-mixin >>> >>> https://docs.djangoproject.com/en/4.0/topics/auth/default/#the-permissionrequiredmixin-mixin >>> >>> >>> Why don't use them? Decorators are for function based views not for >>> class based views. >>> >>> Regards, >>> Albert >>> >>> Hi, >>> >>> as of today, adding a permission_required and / or a login_required >>> decorator on a class based view is a bit ugly, as you have to decorate the >>> dispatch method, which you then have to write down in your class. >>> On top of that, you can't directly use the decorator itself, as you have >>> to wrap it in the method_decorator decorator so it can be applied to a >>> class method instead of a free running function. >>> >>> The problem is that none of those things you have to do in order to use >>> the permission_required and / or login_required decorator are linked to >>> permission / login logic. It's needed only because there's not a proper >>> place to put those decorator, and you can't use them as class decorator. >>> >>> Another problem is that some people might find it a bit weird, and only >>> apply those decorator to a specific method, like get or post, which, if it >>> works, isn't covering other method and might become an issue. It's also not >>> consistent with the function based decorator which cover any http methods >>> at once. >>> >>> In our team, we refactored it a little bit so we could use a class >>> decorator instead. It is much more consistent with the function based view >>> logic, and requires much less code to implement. >>> >>> for the permission_required, it looks like that: >>> ``` >>> from django.contrib.auth.decorators import permission_required as pr >>> from django.utils.decorators import method_decorator >>> >>> >>> def method_permission_decorator(permission, login_url): >>> return method_decorator(pr(permission, login_url=login_url)) >>> >>> def permission_required(permission, login_url="/admin/login"): >>> # build the specific permissions to use >>> specific_permissions = method_permission_decorator(permission, >>> login_url) >>> def wrapper(cls): >>> # decorate the dispatch method with the specific permissions we >>> set >>> cls.dispatch = specific_permissions(cls.dispatch) >>> return cls >>> return wrapper >>> ``` >>> >>> This is specific to our needs of course, but I think it's easy to make >>> more generic, and would add value other teams could benefit from. >>> >>> What it allows is to replace : >>> >>> ``` >>> class MyView(View): >>> # my code here >>> @method_decorator(permission_required(perm)) >>> def dispatch(self, *args, **kwargs): >>> return super().dispatch(*args, **kwargs) >>> ``` >>> >>> by this >>> >>> ``` >>> @permission_required(perm) >>> class MyView(View): >>> # my code here >>> >>> ``` >>> >>> Now, idk if it would make more sense to have another decorator >>> class_permission_required or to have the permission_required decorator >>> tweaked to work with class too, but no matter what's best on that regard, i >>> think it would be a valuable change. >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Django developers (Contributions to Django itself)" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to django-develop...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/django-developers/9529f8c7-e6b4-48e0-8941-efb0123cd5d2n%40googlegroups.com >>> <https://groups.google.com/d/msgid/django-developers/9529f8c7-e6b4-48e0-8941-efb0123cd5d2n%40googlegroups.com?utm_medium=email&utm_source=footer> >>> . >>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Django developers (Contributions to Django itself)" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to django-develop...@googlegroups.com. >>> >> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/django-developers/ppgmuepmxqoefbmikovf%40eywg >>> <https://groups.google.com/d/msgid/django-developers/ppgmuepmxqoefbmikovf%40eywg?utm_medium=email&utm_source=footer> >>> . >>> >> -- > You received this message because you are subscribed to the Google Groups > "Django developers (Contributions to Django itself)" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to django-developers+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/django-developers/bc4de491-163a-4d8c-a85b-07b8f5eb9ae4n%40googlegroups.com > <https://groups.google.com/d/msgid/django-developers/bc4de491-163a-4d8c-a85b-07b8f5eb9ae4n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CAMyDDM0ACjGMTfVgEN99%2B2MoE6XL8SM_jucOHEffObGSDj47zg%40mail.gmail.com.