Not quite, other Mixins, take for example
SingleObjectMixin<https://github.com/django/django/blob/master/django/views/generic/detail.py#L10>
require
access to request, args, kwargs so to utilize the functionality of existing
mixins in init(), we need to set self.request, self.args and self.kwargs in
our dispatch method before dropping down into init(), or do it inside init()

This is the same if we remove the init method entirely, and just try use
the get_object() method on SingleObjectMixin in our overridden dispatch
method.

Since authorization seems to be the main argument so far, I'll use it as an
example - currently we have to do the following:

class MyModel(models.Model):
    name = models.CharField(max_length=100)

    def auth(self, user):
        # do auth

class MyView(SingleObjectMixin, View):
    model = MyModel

    def dispatch(self, request, *args, **kwargs):
        self.request = request
        self.args = args
        self.kwargs = kwargs

        object = self.get_object()
        if object.auth(request.user):
            return super(MyView, self).dispatch(request, *args, **kwargs)
        else:
            # fail somehow

    def get(self, request, *args, **kwargs):
        # behave normally

whereas with some kind of init method, this becomes:

class MyView(SingleObjectMixin, View):
    model = MyModel

    def init(self):
        object = self.get_object()
        if not object.auth(self.request.user):
            # fail somehow

    def get(self, request, *args, **kwargs):
        # behave normally

The example is a bit crude as I just whipped it up, but it gets the point
across I think.

Sorry for dragging this out, I did attempt to explain this earlier however
perhaps I didn't do the best job.

Cheers,
Jordan


On Fri, Nov 9, 2012 at 7:05 PM, Russell Keith-Magee <russ...@keith-magee.com
> wrote:

> Ok… so let's get this straight:
>
>   * init() needs to have access to request, args, kwargs
>   * That means your implementation of dispatch() needs to set them.
>
> Sure. I'll pay that. If you assume that an init() method is required, then
> sure, you need to set up attributes to support it.
>
> What I don't understand is why the need for an init() method isn't being
> challenged in the first place.
>
> Why on earth can't just just take the logic that you're putting in init(),
> and put it *in dispatch()*. The sequence of calls is *identical*, and since
> *args and **kwargs are locals, they don't need to be set anywhere. What's
> the problem with putting the init() logic in the dispatch() method in the
> way I described?
>
> Yours,
> Russ Magee %-)
>
> On Fri, Nov 9, 2012 at 1:37 PM, Jordan Hagan <f...@ephess.co.nz> wrote:
>
>> Hey Russ,
>>
>> The main point of concern which I think you may be missing is that
>> self.kwargs and self.args are set inside dispatch, so using other mixins
>> that require self.kwargs and self.args to be set (most do) will not work,
>> without doing:
>>
>> def dispatch(self, request, *args, **kwargs):
>>     self.args = args;
>>     self.kwargs = kwargs
>>     self.init()
>>     return super(Class, self).dispatch(request, *args, **kwargs)
>>
>> Which isn't very tidy, to me having self.args and self.kwargs be set
>> twice (once in my overridden dispatch method, and once in the original
>> dispatch) feels wrong. I can't give you a good reason for it, it just feels
>> bad every time I do it. The only way to work around this is to override
>> dispatch without calling the original, and essentially duplicate the
>> original dispatch method with an init call added in.
>>
>> Cheers,
>> Jordan
>>
>> On Fri, Nov 9, 2012 at 6:25 PM, Russell Keith-Magee <
>> russ...@keith-magee.com> wrote:
>>
>>>
>>>
>>> On Fri, Nov 9, 2012 at 1:05 PM, Aaron Merriam <aaronmerr...@gmail.com>wrote:
>>>
>>>> Without setting request, args, and kwargs on on the view instance
>>>> (which is done during the base dispatch view), anything in the view that
>>>> assumes these values are present cannot run.
>>>>
>>>> Most of my views end up with functions which retrieve an object and
>>>> then do some basic validation to ensure that a user has permissions, or
>>>> that the object is valid in some fashion, or that some set of conditions is
>>>> met prior to allowing any method call to happen.
>>>>
>>>> I have found that without this init method, the vast majority of my
>>>> views end up re-writing dispatch which includes the super call.  This is
>>>> especially annoying when you have to compare some aspect of the requesting
>>>> user with an object that must be looked up with something from args or
>>>> kwargs.  My view often already has this machinery built in, but it can't
>>>> function without dispatch setting request, args, and kwargs, so to
>>>> accomplish my check, I have to duplicate the lookup code in my dispatch
>>>> method.
>>>>
>>>> I don't propose mine is the best solution, but I know that it is
>>>> non-intrusive, simple, and covers my use cases well.  It is also simple to
>>>> accomplish any number of things since `init` merely needs to return a falsy
>>>> value to allow the request to pass on through, raise an exception if that
>>>> type of failure is desired, or return a response of it wants to hijack the
>>>> view entirely.
>>>>
>>>>
>>> I'm starting to feel like I'm incredibly dense, because I still don't
>>> understand what your use case *is* - or, at least, why what your proposing
>>> provides any significant advantages over what you can do using basic Python
>>> inheritance techniques.
>>>
>>> Specifically, I still can't see why:
>>>
>>> class MyView(View):
>>>     def  dispatch(self, request, *args, **kwargs):
>>>         init()
>>>         return super(MyView, self).dispatch(request, *args, **kwargs)
>>>
>>>     def init():
>>>         # your init logic here
>>>
>>> is superior to the solution provided by using basic Python inheritance:
>>>
>>> class MyView(View):
>>>      def  dispatch(self, request, *args, **kwargs):
>>>         # your init logic here
>>>         return super(MyView, self).dispatch(request, *args, **kwargs)
>>>
>>> You have exactly the same workflow, and exactly the same order of
>>> operations. You don't need to document any special CBV-specific API --
>>> e.g., when/how init() will be invoked, and with what assumptions about the
>>> request environment can be made -- and you don't have to incur the overhead
>>> of a function call (ok - the overhead is tiny, but let's not pretend it's
>>> zero).
>>>
>>> So - can someone explain to me what the advantage is? Why is this init()
>>> method needed?
>>>
>>> Yours,
>>> Russ Magee %-)
>>>
>>>  --
>>> You received this message because you are subscribed to the Google
>>> Groups "Django developers" group.
>>> To post to this group, send email to django-developers@googlegroups.com.
>>> To unsubscribe from this group, send email to
>>> django-developers+unsubscr...@googlegroups.com.
>>> For more options, visit this group at
>>> http://groups.google.com/group/django-developers?hl=en.
>>>
>>
>>  --
>> You received this message because you are subscribed to the Google Groups
>> "Django developers" group.
>> To post to this group, send email to django-developers@googlegroups.com.
>> To unsubscribe from this group, send email to
>> django-developers+unsubscr...@googlegroups.com.
>> For more options, visit this group at
>> http://groups.google.com/group/django-developers?hl=en.
>>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To post to this group, send email to django-developers@googlegroups.com.
> To unsubscribe from this group, send email to
> django-developers+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-developers?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to