【问题标题】:Pass data to template outside view in django?将数据传递给django中的模板外部视图?
【发布时间】:2018-06-11 14:39:07
【问题描述】:

我的意思是,我有经典的始终存在的侧面板,我想在其中显示一些模型数据(例如,现有帖子发布日期、标签等的年/月)。

由于此侧面板始终存在,我还希望避免将检索逻辑放在我定义的每个视图中,因为它是重复的、容易出错/错误、不易维护等。

在 django 中有没有办法定义这样的逻辑并在我创建的每个视图中绑定/注入其结果?

更好的是直接在模板中执行此操作以将其与视图完全分离,所以如果我有一个不需要数据的不同页面(如登录/退出页面)django 不会浪费工作/时间来检索/操作甚至不会显示的东西。

提前致谢

【问题讨论】:

  • 你听说过context_processor吗?这是你需要的

标签: django django-models django-templates django-views


【解决方案1】:

CONTEXT_PROCESSORS 中可用的上下文处理器将在由该设置文件提供支持的每个模板中可用,以创建一个:

  • 在您的项目中创建一个文件,将其命名为context_processors.py,紧邻settings.py
  • 在里面,创建一个函数,就像一个带有参数request 的视图,并且应该返回一个字典

    def function_name(request):
        variable = 'Hello World'
        # all stuff that you want to make available
        return {'variable':variable}
    
  • 转到settings.py,添加你的context_processors.py的路径

    TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'),],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'project_name.context_processors.function_name',
            ],
        },
    },
    ]
    
  • 现在它在由sesttings.py 文件提供支持的所有模板中都可用

    <p>here is the {{ variable }}</p>
    

【讨论】:

  • 我支持这种方法。我几乎在所有项目中都使用它。
  • 太完美了,现在我必须深入研究这个话题。以防万一:是否可以仅为特定模板启用上下文处理器?正如我在问题中所说,我可能有一些页面不需要来自上下文处理器的数据。
  • 好的,它工作得很好,但是可以在父模板中使用上下文处理器数据吗?甚至在父模板中包含的部分?我做了一个简单的测试,似乎不可能,我实际上可以在扩展模板文件中。
【解决方案2】:

这里有两个选择。您可以设计一个可以包含在类声明中的混合,并在其中扩展get_context_data,如下所示:

class SidebarMixin():

   def get_context_data(self, **kwargs):
       context = super(SidebarMixin, self).get_context_data(**kwargs)
       context['sidebar'] = mycontext #insert here your stuff

class MyView(View, SidebarMixin):
   def get_context_data(self, **kwargs):
       context = super(MyView, self).get_context_data(**kwargs)
       context['mycontext'] = mycontext #insert here your stuff

否则你可以定义一个新的模板标签:

@register.inclusion_tag('sidebar.html', takes_context=True)
def sidebar(context):
    return {
        'sidebar': mysidebar_context,
    }

【讨论】:

  • 虽然我仍然更喜欢@Lemayzeur 的答案,但我认为这个答案也非常有用,因为它显示了不同的方法,有人可能会发现更好地依赖于用例
猜你喜欢
  • 1970-01-01
  • 2023-04-06
  • 2014-09-11
  • 2020-03-19
  • 2019-02-16
  • 1970-01-01
  • 2013-07-29
  • 1970-01-01
  • 2018-07-10
相关资源
最近更新 更多