【问题标题】:Access model name in Django CreateView from template从模板访问 Django CreateView 中的模型名称
【发布时间】:2014-08-20 14:33:11
【问题描述】:

我在 Django 1.6 中使用通用 CRUD 视图,例如:

class KanriCreateView(CreateView):
    template_name = 'generic_form.html'

class KanriUpdateView(UpdateView):
    template_name = 'generic_form.html'

等等

注意这些是用作基类的类,我在整个项目的 views.py 文件中子类化它们。

为了保持干燥,我正在为所有创建/更新视图编写一个通用表单模板。

对于更新视图,我可以访问模板中的object,这是我正在更新的实例。然后我使用object.__class__.__name__(通过自定义过滤器)来获取类的名称(这样我就可以自动生成自定义按钮,如“添加用户”、“添加角色”等,这样表单看起来不那么……通用。

当然,当我在CreateView 中使用我的模板时,object 不存在(因为它尚未创建),所以我的自定义buttons.etc 不起作用,我得到一个VariableDoesNotExist例外。

Django 是否在某处提供了 class 以便我可以在模板中使用它?

【问题讨论】:

    标签: python django templates


    【解决方案1】:
    1. 您的第一个视图的名称应该不同,例如KanriCreateView
    2. 它可能会帮助您获取视图类的名称:{{ view.class.name }}
    3. 如果您有权访问视图类(默认情况下由ContextDataMixin 提供),您可以访问视图类的model 属性并获取模型的名称:{{ view.model.__name__ }}

    干杯

    【讨论】:

    • 关于 1 是我在帖子中写签名时的错字,请放心,这不是写的 ;)。我已经修好了。否则,非常感谢。会试一试的。
    • 我相信这在 Django 3 中不再可用> TemplateSyntaxError 变量和属性不能以下划线开头:'view.model.__name__'
    【解决方案2】:

    如果您在 CreateView 中使用 ModelForm,这将不太有效。这是因为您没有指定

    model = MyModel
    

    但您指定的是

    form_class = MyModelForm
    

    所以你可以做的是

    from django.contrib.admin.utils import model_ngettext
    
    model_ngettext(self.form_class._meta.model, 1)
    

    【讨论】:

      【解决方案3】:

      我建议为 Django 2 和 3 更新解决方案:从与 CreateView 关联的 ModelForm 中检索模型详细名称。

      class YourCreateView(CreateView):
      
          form_class = YourModelForm
      
          def get_context_data(self, **kwargs):
              """Add the models verbose name to the context dictionary."""
      
              kwargs.update({
                  "verbose_name": self.form_class._meta.model._meta.verbose_name,})
              return super().get_context_data(**kwargs)
      

      现在您可以在模板中使用{{ verbose_name }}

      请注意上面代码 sn-p 中的 double _meta:第一个用于从 ModelForm 访问模型,而第二个用于访问模型的详细名称。

      与国际化一样,请注意,如果您的模型使用如下所示的 ugettext,那么详细名称将自动在模板中翻译。

      from django.utils.translation import ugettext_lazy as _
      
      class MyModel(models.Model):
          class Meta:
              verbose_name = _("your verbose name")
      

      【讨论】:

        猜你喜欢
        • 2011-09-28
        • 2016-04-14
        • 2011-11-17
        • 1970-01-01
        • 1970-01-01
        • 2013-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多