在同一模板中渲染多个视图的最佳方法是什么?

时间:2015-04-02 15:04:57

标签: django

方案

我需要在同一个视图中从第三方应用渲染2个不同的视图。有问题的观点用于登录和注册。

每个视图的模板只包含一个包含标记,用于呈现通用表单。


解决方案

我提出的解决方案是为每个视图注册一个标记,以创建template.Node来呈现每个视图。

from django import template

from third_party_app import LoginView, SignupView

register = template.Library()

@register.tag
def login_form(parser, token):
    return ViewNode(LoginView, template_name=get_template_name(token))

@register.tag
def signup_form(parser, token):
    return ViewNode(SignupView, template_name=get_template_name(token))


class ViewNode(template.Node):

    def __init__(self, view_class, **kwargs):
        self.view_class = view_class
        self.kwargs = kwargs

    def render(self, context):
        request = context['request']
        self.kwargs['request'] = request
        view = self.view_class(**self.kwargs)
        response = view.get(request)
        response.render()
        return response.content


def get_template_name(token):
    tag_name, template = token.split_contents()
    return str(template[1:-1])

主视图的模板如下所示:

<div>

    {% login_form 'account/login.html' %}

</div>

... some other html ...

<div>

    {% signup_form 'account/signup.html' %}

</div>


每个登录和注册视图的模板仅包含一个包含标记,用于呈现通用表单的另一个模板。

所以accounts / login.html就是这样:

{% render_login_form %}

并且包含标记看起来像这样

@register.inclusion_tag('account/snippets/form.html', takes_context=True)
def render_login_form(context):
    return {'form': context['form'],
            'primary_btn_label': 'Sign In',
            'secondary_btn_label': 'Forgot Password?',
            'tertiary_btn_label': 'Sign Up?',
            'col_offset': '3',
            'col_width': '9'}


问题

它有效,但我想知道两件事。

  1. 这是在同一视图中渲染2个视图的最佳方法吗?

  2. 感觉有两个步骤可以实现这一目标。有没有更简单的方法来解决这个问题?

1 个答案:

答案 0 :(得分:0)

我做了类似的事情:

前两个模板login.htmlsignup.html。在这些模板中,我访问了formprimary_btn_label等上下文变量以及render_login_form包含标记中的其他内容。

但是我有一个自定义上下文处理器(请参阅context processors上的Django文档)初始化这些变量(如form等)

上下文处理器(保存在myapp/context_processors.py)看起来像这样:

from .forms import LoginForm, RegisterForm

def login_register_form(request):
    login_popup_form = LoginFormForPopup()
    register_popup_form = RegisterFormForPopup()
    context = {
        'login_popup_form': login_popup_form,
        'register_popup_form': register_popup_form,
    }

    return context

自定义上下文处理器在Django设置文件中启用,方法是将其添加到TEMPLATE_CONTEXT_PROCESSORS变量中:

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'myapp.context_processors.login_register_form',
)

希望这有帮助!