【问题标题】:" django.template.exceptions.TemplateSyntaxError: Invalid block tag on line 5: 'get_verbose_name', expected 'empty' or 'endfor'. "“ django.template.exceptions.TemplateSyntaxError:第 5 行的块标记无效:'get_verbose_name',预期为 'empty' 或 'endfor'。”
【发布时间】:2017-03-03 01:20:46
【问题描述】:

我一直在寻找在视图/模板中显示来自 Django 模型的数据的方法。我仍然只是一个初学者,但已经阅读了很多 stackoverflow 以获得知识。

我正在尝试做的事情的实现我从这个线程中挑选出来的:Display table of objects django

输入 template.html 和 views.py 后(稍微修改我的 views.py - 将 MyModel 更改为 Environment Model)我收到错误:

"Invalid block tag on line 5: 'get_verbose_name', expected 'empty' or 'endfor'. Did you forget to register or load this tag?"

这个错误是指<th>{% get_verbose_name field %}</th>

在模板.html中

我尝试为模型中的每个字段添加详细名称,但这不是明显的问题。我的views.py、models.py和template.html附加在一个pastebin中。

我的views.py 和template.html 与在链接的stackoverflow 线程中检查的解决方案几乎完全相同。我的问题基本上是理解为什么会出现这个错误,以及如何解决它

感谢您的帮助

tables.html

<table>
<thead>
    <tr>
        {% for field in cached_fields %}
            <th>{% get_verbose_name field %}</th>
        {% endfor %}
    </tr>
</thead>
<tbody>
        {% for d in data %}
            <tr>
                {% for field in fields %}
                    <td>{% get_value_from_key d field %}</td>
                {% endfor %}
            </tr>
        {% endfor %}
</tbody>

Views.py

from __future__ import unicode_literals
from django.views import generic
from django.shortcuts import render, render_to_response, get_object_or_404,     redirect
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpRequest, HttpResponse
from django.template import RequestContext
import simplejson as json
#from appDatabase.forms import *
from . import forms;
from . import models;

class AppTable(generic.TemplateView):
    template_name = "appDatabase/tables.html"

def index(request) :
    fields    = Environment._meta.fields
    data      = json.loads(serializers.serialize("json", Environment.objects.all()))

    def parse_data(data):

        result = []

        # flatten the dictionary
        def flatten_dict(d):
            """
            Because the only nested dict here is the fields, let's just
            remove the 'fields' suffix so that the fields can be loaded in
            template by name
            """
            def items():
                for key, value in d.items():
                    if isinstance(value, dict):
                        for subkey, subvalue in flatten_dict(value).items():
                            yield subkey, subvalue
                    else:
                        yield key, value

            return dict(items())
        for d in data:
            # change the 'pk' key name into its actual name in the database
            d[Environment._meta.pk.name] = d.pop('pk')
            # append the flattend dict of each object's field-value to the result
            result.append(flatten_dict(d))

        return result

        context_instance  = RequestContext(request, {
        'data'      : parse_data(data),
        'fields'    : fields, })
    return TemplateResponse(request, 'tables.html', context_instance)

模型.py

from __future__ import unicode_literals
from django.utils.encoding import python_2_unicode_compatible
import uuid
from django.contrib.auth.models import User
from django.db import models
from django import forms
from django.forms import ModelForm;
# Create your models here.


class Environment(CommonInfo):
    environment_Type = models.CharField(verbose_name ="Environment Type", max_length=10)
    environment_Name = models.CharField(verbose_name ="Environment Name", max_length=10)

【问题讨论】:

标签: python django django-templates


【解决方案1】:
  • 非常简单的方法

在您的模板中使用{{field.verbose_name}} 而不是{% get_value_from_key d field %},这种方法可以正常工作并经过测试:

In [1]: from django.template import Template,Context

In [2]: t=Template("""""")

In [3]: t=Template("""{% for field in fields %}
   ...:                     <td>{{field.verbose_name}}</td>
   ...:                 {% endfor %}""")

In [4]: from h.models import MyClass

In [5]: c = Context({"fields":MyClass._meta.fields,})

In [6]: t.render(c)
Out[6]: u'\n                    <td>ID</td>\n                \n                    <td>Name</td>\n
  • 非常复杂的方法

首先你需要根据django注册自定义模板标签doc:

应用程序应包含templatetags 目录,与models.pyviews.py 等处于同一级别。如果不存在,请创建它 - 不要忘记__init__.py 文件以确保该目录被视为 Python 包。 然后在这里创建你想要的python文件名文件名mytag.py 在模块顶部附近,放置以下内容:

from django import template

register = template.Library()

注册标签使用函数助手simple_tag 在你的函数之前添加:

@register.simple_tag

然后键入您的标签作为函数,它需要两个参数instancename(即文件名)然后返回verbose_name

def get_verbose_name(instance):
    return instance.verbose_name

把所有东西放在一起:

from django import template

register = template.Library()
@register.simple_tag
def get_verbose_name(instance, field_name):
       return instance.verbose_name

然后在你的模板中使用它,加载mytag模块的使用标签:

{% load mytag %} 
{% get_verbose_name field_instance %}

返回 field_instance.verbose_name

【讨论】:

  • {% get_verbose_name field_instance "name_of_field" %} 应为 {% get_verbose_name field_instance %} field_instance 包含 verbose_name。所以过滤器需要做一些类似的事情:return field_instance.verbose_name,如果verbose_name不存在,可能会写一个后备(后备到field_name本身?)。这两个属性都住在field_instance
  • 非常感谢您的详细回答,并感谢您考虑到 OP 的理解水平:p
猜你喜欢
  • 2013-06-10
  • 2021-12-08
  • 1970-01-01
  • 2015-07-08
  • 2017-08-05
  • 1970-01-01
  • 2020-11-13
  • 2021-02-02
  • 2018-03-25
相关资源
最近更新 更多