Django - Why should I ever use the render_to_response at all?

后端 未结 2 526
自闭症患者
自闭症患者 2020-12-01 14:06

consider this:

return render(request, \'index.html\', {..context..})
return render_to_response(\'index.html\', {..context..})

On the one ha

2条回答
  •  刺人心
    刺人心 (楼主)
    2020-12-01 14:56

    Too long; didn't read

    When context processors are applied

    When you use RequestContext, the variables you supply directly are added first, followed any variables supplied by context processors. This means that a context processor may overwrite a variable you’ve supplied, so take care to avoid variable names which overlap with those supplied by your context processors.


    Let's see first how the methods render_to_response and render are defined.

    def render_to_response(*args, **kwargs):
        """
        Returns a HttpResponse whose content is filled with the result of calling
        django.template.loader.render_to_string() with the passed arguments.
        """
        httpresponse_kwargs = {'content_type': kwargs.pop('content_type', None)}
    
        return HttpResponse(loader.render_to_string(*args, **kwargs), **httpresponse_kwargs)
    
    def render(request, *args, **kwargs):
        """
        Returns a HttpResponse whose content is filled with the result of calling
        django.template.loader.render_to_string() with the passed arguments.
        Uses a RequestContext by default.
        """
        httpresponse_kwargs = {
            'content_type': kwargs.pop('content_type', None),
            'status': kwargs.pop('status', None),
        }
    
        if 'context_instance' in kwargs:
            context_instance = kwargs.pop('context_instance')
            if kwargs.get('current_app', None):
                raise ValueError('If you provide a context_instance you must '
                                 'set its current_app before calling render()')
        else:
            current_app = kwargs.pop('current_app', None)
            context_instance = RequestContext(request, current_app=current_app)
    
        kwargs['context_instance'] = context_instance
    
        return HttpResponse(loader.render_to_string(*args, **kwargs),
                            **httpresponse_kwargs)
    

    Isn't there a better way to enforce RequestContext as the default?

    Note in the section Subclassing Context: RequestContext

    If you’re using Django’s render_to_response() shortcut to populate a template with the contents of a dictionary, your template will be passed a Context instance by default (not a RequestContext)

    From the code above the method render_to_response calls the method loader.render_to_string where context_instance parameter is checked in this line.

    Code listing for the method render_to_string

    def render_to_string(template_name, dictionary=None, context_instance=None,
                         dirs=None):
        """
        Loads the given template_name and renders it with the given dictionary as
        context. The template_name may be a string to load a single template using
        get_template, or it may be a tuple to use select_template to find one of
        the templates in the list. Returns a string.
        """
        dictionary = dictionary or {}
        if isinstance(template_name, (list, tuple)):
            t = select_template(template_name, dirs)
        else:
            t = get_template(template_name, dirs)
        if not context_instance:
            return t.render(Context(dictionary))
        # Add the dictionary to the context stack, ensuring it gets removed again
        # to keep the context_instance in the same state it started in.
        with context_instance.push(dictionary):
            return t.render(context_instance)
    

    Can't we do simple to use decorator with render?

    We can write decorator for this, but your question is subjective. If it's easy to use or not is hard to tell. It very much depends


    Is there a way to avoid passing request as an argument?

    render() is the same as a call to render_to_response() with a context_instance argument that forces the use of a RequestContext.

    class RequestContext is defined in this line. Code listing for the class RequestContext

    class RequestContext(Context):
        """
        This subclass of template.Context automatically populates itself using
        the processors defined in TEMPLATE_CONTEXT_PROCESSORS.
        Additional processors can be specified as a list of callables
        using the "processors" keyword argument.
        """
        def __init__(self, request, dict_=None, processors=None, current_app=None,
                use_l10n=None, use_tz=None):
            Context.__init__(self, dict_, current_app=current_app,
                    use_l10n=use_l10n, use_tz=use_tz)
            if processors is None:
                processors = ()
            else:
                processors = tuple(processors)
            updates = dict()
            for processor in get_standard_processors() + processors:
                updates.update(processor(request))
            self.update(updates)
    

    Last question doesn't need an answer, if you understand how the code behind Django actually works.

提交回复
热议问题