【问题标题】:Django 2.1 -- Display model verbose_name from meta in ListViewDjango 2.1 -- 在 ListView 中显示来自 meta 的模型 verbose_name
【发布时间】:2019-08-09 13:39:16
【问题描述】:

第一段代码运行良好;供参考。

#Basic Model
class MyTestModel(models.Model):
    record = models.CharField(max_length=100)

    def __str__(self):
        return self.record

    #Specify verbose_name
    class Meta:
        verbose_name = 'UniqueNameExample'
        verbose_name_plural = verbose_name


#Generic ListView.
class MyTemplateView(ListView):
    model = MyTestModel
    template_name = 'base.html'
    context_object_name = 'model_list'
    ordering = ['record']



#Python block in HTML template. So far, so good. 
{% for item in model_list %}
    {{ item.record }}<br>
    #{{ item }} also works
{% endfor %}

我正在尝试访问模型的详细名称('UniqueNameExample')和视图中的模型列表。我试过注册一个过滤器、一个标签和 simple_tag。

类似:templatetags/verbose.py

from django import template
register = template.Library()

@register.filter (or @register.tag or @register.simple_tag)
def verbose_name(obj):
    #Could be verbose_name(model) or whatever input
    return obj._meta.verbose_name

然后在

{% load verbose %}

在我的 HTML(也可以正常工作)中,我会尝试这样的事情:

{{ object|verbose_name }}

我会得到错误“str”对象没有属性“_meta”。如果使用标签,错误是一样的:

{% verbose_name object %}

注意:标签显然适用于早期版本,但也许我使用不正确?不要求访问“记录”的模型字段verbose_name,顺便说一句——这在SO上得到了充分的回答。

我尝试过的一件事是如果我在 MyTemplateView 下设置了以下内容:

queryset = model._meta.verbose_name 

这样做的问题是它覆盖了 model_list,我剩下的唯一结果是“UniqueNameExample”,而无法访问我在模型中使用的记录。

我知道 _meta 的 private=True (不确定这是否相关或值得探索/可能破坏),但 Django 管理员在创建的模型列表中显示了 verbose_name(如果设置),所以我不明白为什么我可以' 不做同样的事情(在源代码中准确地追溯它是如何做的也有一段艰难的时间)。也许它不是一个通用的 ListView 而是一个 MixIn?基于函数?

包含数千个模型的大型(ish)数据库,每个模型都有唯一的 verbose_name[s];非常希望保持简单。

【问题讨论】:

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


    【解决方案1】:

    编辑:从 Dominique Barton @https://blog.confirm.ch/accessing-models-verbose-names-django-templates/ 找到了一个绝妙的解决方案

    首先,在应用程序级别创建一个 templatags 文件夹并填充一个 init 文件。接下来,创建一个模板标记文件。像verbose.py这样的东西。

    from django import template
    register = template.Library()
    
    @register.simple_tag
    def verbose_name(value):
    #Django template filter which returns the verbose name of a model.
    #Note: I set my verbose_name the same as the plural, so I only need one tag. 
        if hasattr(value, 'model'):
            value = value.model
        return value._meta.verbose_name
    

    接下来,应该修改 ListView。

    from django.views.generic.list import ListView as DjangoListView
    from .models import MyTestModel
    
    
    class ListView(DjangoListView):
        #Enhanced ListView which includes the `model` in the context data,
        #so that the template has access to its model class.
        #Set normally
        model = MyTestModel
        template_name = 'base.html'
        context_object_name = 'model_list'
        ordering = ['record']
    
        def get_context_data(self):
            #Adds the model to the context data.
            context = super(ListView, self).get_context_data()
            context['model'] = self.model
            return context
    

    不要忘记添加 urls.py 的路径:

    path('your_extension/', views.ListView.as_view(), name='base')
    

    最后,加载标签并正常遍历“记录”:

    {% load verbose %}
    
    
    <h1> {% verbose_name model%} </h1>
    
    <ul style='list-style:none'>
    {% for item in model_list %}
        <li>{{ item }}}</a></li> 
    {% endfor %}
    </ul>
    

    分页也像宣传的那样工作。

    【讨论】:

    • 使用 simple_tag 与直接在上下文中添加想要的字符串有什么好处吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2023-01-30
    • 2023-01-03
    • 2020-12-29
    • 2021-05-18
    • 1970-01-01
    相关资源
    最近更新 更多