Django:模板语法错误,过滤器无效

问题描述 投票:0回答:4

我正在尝试使用变量访问字典中的值,所有这些都在遵循 Django 模板语言的 HTML 文件中。 Django 的模板语言不允许您使用变量作为键来访问字典,因此我决定使用 Django 过滤器来完成此操作。但是,我收到“无效过滤器”错误,但我不明白为什么。

我的 html 文件

<table class="table">
<tbody>
    <tr>
        <th scope="row">Username</th>
        <th scope="row">Full Name</th>
        <th scope="row">Points</th>
        {% for subject in subjects %}
        <th scope="row">{{ subject }}</th>
        {% endfor %}
    </tr>
    {% for user in users %}
    <tr>
        <td>
            <a href="{% url 'profile' username=user.username %}">{{ user.username }}</a>
        </td>
        <td>{{ user.first_name }} {{ user.last_name }}</td>
        <td>{{ user.profile.points.total }}</td>
        {% for subject in subjects %}
        <td>{{ user.profile.points|keyvalue:subject }}</td>
        {% endfor %}
    </tr>
    {% endfor %}
</tbody>

我的过滤器.py

from django import template
register = template.Library()

@register.filter
def keyvalue(dict, key):    
    return dict[key]

我的错误信息

TemplateSyntaxError at /leaderboard/
Invalid filter: 'keyvalue'

谢谢您的帮助:D

编辑:根据要求粘贴我的views.py和urls.pu

views.py

def leaderboard(request):
    global leaderboard_public
    users = sorted(User.objects.all(), key=lambda t: t.profile.points['total'], reverse=True)

    if request.method == "POST":
        leaderboard_public = not leaderboard_public
        return redirect(leaderboard)
    subjects = list(Subject.objects.values('subject_name'))
    subjects = [i['subject_name'] for i in subjects]
    print(subjects)
    return render(request, "leaderboard.html", {
        "users": users,
        "subjects": subjects,
        # "leaderboard_public": leaderboard_public,
    })

url.py

from accounts import views as accountsViews
from puzzles import views as puzzlesViews

urlpatterns = [
url(r'^admin/', admin.site.urls),

url(r'^signup/$', accountsViews.signup_without_email, name="signup"),
url(r'^activate/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$',
    accountsViews.activate, name='activate'),
url(r'^logout/$', authViews.LogoutView.as_view(), name='logout'),
url(r'^login/$', authViews.LoginView.as_view(template_name='login.html'), name="login"),
# url(r'^puzzles/$', puzzlesViews.puzzles, name="puzzles"),
url(r'^puzzle/(?P<puzzleID>.+)/edit/$', puzzlesViews.editPuzzle, name="editPuzzle"),
url(r'^puzzle/(?P<puzzleID>.+)/$', puzzlesViews.puzzle, name="puzzle"),
url(r'^scheduled/$', puzzlesViews.scheduled, name="scheduled"),
url(r'^closed/$', puzzlesViews.closed, name="closed"),
url(r'^leaderboard/$', accountsViews.leaderboard, name="leaderboard"),
# url(r'^leaderboard/(?P<subject>.+)/$', accountsViews.leaderboard_subject, name="leaderboard"),
# url(r'^submissions/$', puzzlesViews.submissions, name="submissions"),
url(r'^profile/(?P<username>.+)/submissions$', puzzlesViews.submissions, name="submissions"),
url(r'^profile/(?P<username>.+)/edit/$', accountsViews.editProfile, name="editProfile"),
url(r'^profile/(?P<username>.+)/$', accountsViews.profile, name="profile"),
url(r'^create/$', puzzlesViews.create, name="create"),
# url(r'^$', views.home, name="home"),
url(r'^$', puzzlesViews.puzzles, name="puzzles"),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

如果需要任何其他信息,请告诉我。

django django-templates django-filters
4个回答
7
投票

我尝试了

{% load crispy_forms_filters %}
,它对我有用!


6
投票

使用 Django 文档 和其他用户的答案,这是我需要做的一切才能使其工作

  1. 创建一个名为 templatetags
  2. 的文件夹
  3. 在其中创建一个 filter.py 文件
  • 我还创建了一个 init.py 文件,但在 Python 3+ 中可能没有必要
  1. 在根文件夹内的setting.py文件中,我添加了以下内容
    INSTALLED_APPS = [
    ...
    'templatetags.filter']

    TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
            **'libraries':{
                'filter': 'templatetags.filter',**
            }
        },
    },
    ]
  1. 在新创建的filter.py中,我定义了我的过滤器
    import datetime
    from django import template
    
    register = template.Library()
    
    @register.filter(name="my_filter_name")
    def my_filter_name(input):
        output = do_something_with_input(input)
        return output
    
    register.filter('my_filter_name', my_filter_name)
  1. 在我的 html 模板中加载filter(在前面的步骤中配置)
{% extends "base.html" %}

{% load filter %}

...

Obs:Django 的文档似乎不是我一段时间以来见过的最好的文档。事实上,它应该包含更多示例并且更清晰。

我希望这可以帮助任何摆弄 Django 的人:)


4
投票

看起来您忘记将

filter.py
模型加载到模板中。要使用自定义过滤器,您需要将
filter.py
放入
app/templatetags
目录中(注意此目录应包含
__init__.py
)并使用语法
{% load filter %}
将其加载到模板中。请参阅文档此处


0
投票

要在使用 django jazzmin 或 django-admin-logs 时轻松解决 django 中的此错误,只需 将 django 版本降级到 5.0.1 以下。 我建议使用 django==4.2.16。 这很有帮助。 谢谢。

© www.soinside.com 2019 - 2024. All rights reserved.