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

Gar*_*nzo 5 python django django-class-based-views

我正在{{ title }}为我的项目的每一页设置一个。有时这title是一个静态字符串,例如Enter your Name,有时它基于该页面上的相关对象,例如Employee.first_name.

为了创建context['title'],我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
Run Code Online (Sandbox Code Playgroud)

我觉得有一个混入是理想的,我以某种方式只是传入变量title,我的context字典将context['title']根据传入的变量自动添加。

这可能吗?有没有一种方法来创建一个mixin使得所有我需要做的就是传递一个变量,它会给我一个上下文只是为标题,而不是写出来的代码块的每一个观点?

Gwy*_*idD 5

是的,这是可能且简单的:

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
Run Code Online (Sandbox Code Playgroud)

你使用它:

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
Run Code Online (Sandbox Code Playgroud)

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

{# base.html #}
<html>
  <head>
    <title>{% block page_title %}My page{% endblock %}</title>
  </head>
</html>
Run Code Online (Sandbox Code Playgroud)
{# 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 #}
Run Code Online (Sandbox Code Playgroud)


Eli*_*iot 2

我通常用 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
Run Code Online (Sandbox Code Playgroud)

在您的视图中,您可以执行以下操作:

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
Run Code Online (Sandbox Code Playgroud)

  • 这行不通。您的意思可能是“context['title'] = self.get_title()”? (2认同)