Django CBV - 如何避免为每个视图重复get_context_data以获得自定义标题?

时间:2015-08-25 15:05:49

标签: python django django-class-based-views

我为项目的每个页面设置$ bash bash_file.sh 0。有时,此bash_file.sh line 2: 4: no such file or directory是一个静态字符串,例如{{ title }},有时它基于该页面上的相关对象,例如title

要创建Enter your Name,我在每个基于类的视图中使用Employee.first_name。但这似乎导致我每次都重复一大堆代码,而且我希望以某种方式减少它。

例如,要为每个页面编写自定义标题,我必须写下这个:

context['title']

我觉得有一个mixin是理想的,我只是传入get_context_data的变量而我的def get_context_data(self, **kwargs): context = super(SomeView, self).get_context_data(**kwargs) context['title'] = 'Title for This page' return context 词典将自动添加title基于传入的变量。

这可能吗?有没有办法创建一个mixin,这样我所要做的就是传入一个变量,它会给我一个上下文只是的标题而不是写出那块代码对于每一个视图?

2 个答案:

答案 0 :(得分:4)

是的,这是可能的,也很简单:

class YourTitleMixin(object):
    title = None # or your default title if you won't provide any

    def get_title(self):
        return self.title

    def get_context_data(self, **kwargs):
        context= super(YourTitleMixin, self).get_context_data(**kwargs)
        context['title'] = self.get_title()
        return context

你用它:

def YourPageView(YourTitleMixin, DetailView):
    title = "Your Page Title" # you can either use this ...

    def get_title(self):
        return self.get_object().name # ... or that, if your title should be generated from some data

但这有必要吗?您是否只在模板中使用过一次标题?你在视图之间共享一个模板吗?也许你可以纯粹在你的模板中做到这一点?例如:

{# base.html #}
<html>
  <head>
    <title>{% block page_title %}My page{% endblock %}</title>
  </head>
</html>
{# detail.html #}
{% extends "base.html" %}
{% block title %}{{ article.name }} - {{ block.super }}{% endblock %}
{# will result in "article name - My Page". You don't need to use super if you don't want to #}

答案 1 :(得分:1)

我通常用mixin解决这个问题:

class TitleMixin(object):
    """Pass a defined title to context"""

    title = None

    def get_title(self):
        return self.title

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title'] = self.get_title()

        return context

在你的观点中,你可以这样做:

class BlogIndex(TitleMixin, ListView):
    title = 'Blog entries'

class EntryDetail(TitleMixin, DetailView)
    def get_title(self): # for dynamic title, such as coming from a model field
        return self.object.title