Opened 6 years ago

Last modified 6 years ago

#28943 closed Cleanup/optimization

Unenforce manual get_context_data() — at Version 10

Reported by: James Pic Owned by: nobody
Component: Generic views Version: 2.0
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by James Pic)

Currently, TemplateView inherits render_to_response(context) from TemplateResponseMixin which requires a context argument.

This means that when your TemplateView subclass wants to return the TemplateResponse with the default context, you still have to create and pass the default context:

class YourView(TemplateView):
    def post(self, request, *a, **k):
        if not self.dostuff():
            return http.HttpResponseBadRequest()

        context = self.get_context_data(*k)
        return self.render_to_response(context)

The reason for this is that ContentMixin defines get_context_data(), and TemplateResponseMixin defines render_to_response(context, ...), TemplateResponse mixes the two in get():

class TemplateView(TemplateResponseMixin, ContextMixin, View):
    """
    Render a template. Pass keyword arguments from the URLconf to the context.
    """
    def get(self, request, *args, **kwargs):
        context = self.get_context_data(**kwargs)
        return self.render_to_response(context)

I think it would be more usable as such:

class TemplateView(TemplateResponseMixin, ContextMixin, View):
    """
    Render a template. Pass keyword arguments from the URLconf to the context.
    """
    def get(self, request, *args, **kwargs):
        return self.render_to_response(**kwargs)

    def render_to_response(self, context=None, **kwargs):
        context = context or self.get_context_data(**kwargs)
        return self.render_to_response(context)

Then, users could call render_to_response() in their code without dealing with a context they don't override because they are satisfied with the default (which adds view=self in the context), ie:

class YourView(TemplateView):
    def get(self, request, *a, **k):
        self.token = self.generatetoken()
        return self.render_to_response(**k)

    def post(self, request, *a, **k):
        if not self.dostuff():
            return http.HttpResponseBadRequest()
        return self.render_to_response(**k)

Change History (10)

comment:1 by James Pic, 6 years ago

Description: modified (diff)

comment:2 by James Pic, 6 years ago

Description: modified (diff)

comment:3 by Tim Graham, 6 years ago

Easy pickings: unset

The ticket summary is cryptic. Please describe the use case in more detail. I don't see an indication of where TemplateResponse.get(self, request, *args, **kwargs) lives.

comment:4 by James Pic, 6 years ago

Description: modified (diff)

comment:5 by James Pic, 6 years ago

Thanks for your feedback, I rewrote the issue, does it make any sense now ?

comment:6 by James Pic, 6 years ago

Description: modified (diff)

comment:7 by James Pic, 6 years ago

Description: modified (diff)

comment:8 by James Pic, 6 years ago

Description: modified (diff)

comment:9 by James Pic, 6 years ago

Description: modified (diff)

comment:10 by James Pic, 6 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top