Django:TemplateSyntaxError,无效的过滤器

7
我将会为您翻译以下内容:

我正在尝试在遵循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>

我的filter.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.py代码
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,
    })

urls.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)

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


不确定问题出在哪里。一切看起来都没问题。至少,你展示的代码/文件没有问题。你使用的Python和Django版本是什么?你是否将filter.py文件放在有效的Django应用程序中?你创建filter.py的应用程序是否列在INSTALLED_APPS中?文件夹是否被准确地命名为templatetags?该文件夹内是否有一个__init__.py文件?你是否在这行代码{{ user.profile.points|keyvalue:subject }}之前调用了{% load filter %} - Vitor Freitas
3个回答

7

我尝试了{% load crispy_forms_filters %},它对我起作用了!


6

使用Django文档和其他用户的答案,这是我所做的一切内容,以使其正常工作

  1. 创建一个名为templatetags的文件夹
  2. 在其中创建一个名为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',**
            }
        },
    },
    ]

在新建的 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模板中加载(在之前步骤中配置的)过滤器
{% extends "base.html" %}

{% load filter %}

...

注意:Django的文档似乎不是我最近看到的最好的文档。事实上,它应该包含更多的示例并且更清晰易懂。
我希望这能帮助那些在使用Django时瞎折腾的人 :)

请修改您的回答以改善文本排版(不要无缘无故地使用标题)。 请参见[答案]。 - Gander
我已经完成了所有这些。但是这个解决方案总是会出现“指定的无效模板库”错误... - Conor
1
太好了。我之前遇到了tojson过滤器的问题,但是我自己创建了一个并且它完美地解决了我的问题。 - SHIVAM SINGH

4

看起来你忘记在模板中加载filter.py模型。要使用自定义过滤器,您需要将filter.py放置在app/templatetags目录中(请注意,该目录应包括__init__.py),并使用语法{% load filter %}在模板中加载它。有关详细信息,请参阅此处的文档。


我的错,因为我没有发布完整的HTML文件,但是我已经加载了过滤器,并根据文档完成了所有外围过滤器设置。事实上,我在同一应用程序中的另一个HTML文件中使用了不同的过滤器,那个过滤器运行良好。似乎由于某种原因,这个特定的过滤器出了问题,但我无法找出原因。 - ohjuny
@ohjuny,在添加了这个新的过滤器后,你重启了 Django 吗? - neverwalkaloner
是的,我已经尝试重新启动我的Django服务器。但它似乎仍然无法正常工作。 - ohjuny
@ohjuny 嗯..你在这个特定的模板中有使用{% load filter %}标签吗?这个标签应该在每个模板中都要使用。另外,你能否检查一下是否存在例如文件名之类的拼写错误?因为我已经在我的测试项目中检查了你的过滤器,它是可以正常工作的。 - neverwalkaloner
嗯,这很奇怪。我也在本地测试过了——只是复制并粘贴了 OP 的过滤器,它正常工作了... - Vitor Freitas
自定义过滤器将使用哪些数据库模型?手册中没有指定。它与IntegerField不兼容。 - Conor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接