Opened 10 years ago

Closed 10 years ago

#21964 closed Cleanup/optimization (wontfix)

ProcessFormView should pass **kwargs to get_context_data()

Reported by: Chris Jerdonek Owned by: nobody
Component: Generic views Version: 1.6
Severity: Normal Keywords:
Cc: chris.jerdonek@… Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

In the ProcessFormView class, keyword arguments to the view aren't available in the template context by default.

From what I can tell, changing this behavior (so that one can customize other aspects of the template) requires relying on undocumented implementation details of Django views (namely that View.as_view() sets self.kwargs). For example:

def get_context_data(self, **kwargs):
    # ProcessFormView doesn't pass the view's keyword arguments in its
    # calls to get_context_data(), so we need to add them back manually.
    context = self.kwargs.copy()
    context.update(kwargs)
    return context

I think things would be simpler and more consistent if ProcessFormView passed the view's **kwargs to get_context_data() in the first place, in which case ProcessFormView could implement its own version of get_context_data() that would restrict the context. This would be more DRY by eliminating the need to read self.kwargs when overriding get_context_data(). This will also reduce potential confusion between the **kwargs argument and the undocumented self.kwargs attribute.

Change History (5)

comment:1 by Chris Jerdonek, 10 years ago

Cc: chris.jerdonek@… added

comment:2 by Tim Graham, 10 years ago

Component: UncategorizedGeneric views

FWIW, pushing kwargs to the context has been called an anti-pattern in #19878 and we're planning to deprecate that behavior in TemplateView. I guess this change may still have merit, but I haven't looked into the details.

comment:3 by Chris Jerdonek, 10 years ago

Thanks for the pointer to the current thinking. In that case, it seems like self.kwargs should be documented somewhere as the recommended way to access the keyword arguments passed to a view (as opposed to **kwargs to whatever method is being overridden). Currently, self.kwargs is set by as_view() here. One place self.kwargs could be documented is in the attributes subsection of the django.views.generic.base.View documentation. It doesn't currently seem to be documented anywhere that I've come across. Maybe the documentation for as_view() could also include a note about setting self.kwargs.

comment:4 by Chris Jerdonek, 10 years ago

Sorry, scratch my last comment. I misread your comment that "pushing kwargs to the context has been called an anti-pattern" as saying "pushing kwargs to get_context_data() has been called an anti-pattern." self.kwargs need not be documented if the view's keyword arguments are passed to get_context_data() as I suggested in this issue.

comment:5 by Marc Tamlyn, 10 years ago

Resolution: wontfix
Status: newclosed

The self.kwargs attribute is documented (https://docs.djangoproject.com/en/dev/topics/class-based-views/generic-display/#dynamic-filtering), however this is not the most obvious location for the documentation.

The understanding with get_context_data is that kwargs will put in the context. Automatically passing the url kwargs into the context (from get() or similar) is an antipattern (#19878). If you really wish to access them, you can access view.kwargs in the context as the view instance is passed into the context.

If you feel strongly that we should improve the documentation of self.args and self.kwargs, and have a concrete proposal on where to do so, please open a new ticket.

Note: See TracTickets for help on using tickets.
Back to Top