简体   繁体   English

要在 base.html (Django) 中使用的上下文变量

[英]Context variable to be used in base.html (Django)

I need a certain context variable in my base.html.我的 base.html 中需要一个特定的上下文变量。 This is to contain a set of usernames, eg [name1, name2, name3, name4,] .这是包含一组用户名,例如[name1, name2, name3, name4,] If a logged in user's username is part of this list, I give said user certain preferential treatment and show something in the navbar.如果登录用户的用户名在此列表中,我会给予该用户一定的优惠待遇并在导航栏中显示一些内容。

To achieve this, I wrote a template tag :为了实现这一点,我写了一个模板标签

from django import template
from django.db import models
from django.contrib.auth.models import User

register = template.Library()

VIPS = [name1, name2, name3, name4,]

@register.simple_tag
def verified(user):
    return VIPS

register.simple_tag(verified)

And then in base.html , I added {% load verified %} at the top, and then:然后在base.html ,我在顶部添加了{% load verified %} ,然后:

{% if user.username in verified %}
<!-- do something -->
{% endif %}

This isn't working.这不起作用。 What am I doing wrong?我究竟做错了什么? I suspect I've written my template tag incorrectly, but I've tried several, more complex approaches (in vain), at least this simpler one made logical sense to me.我怀疑我写错了模板标签,但我尝试了几种更复杂的方法(徒劳无功),至少这个更简单的方法对我来说合乎逻辑。

My project's a legacy Django 1.5 project with Python 2.7 .我的项目是带有Python 2.7的旧版Django 1.5项目。

You don't need the register.simple_tag(verified) line, as the @register decorator is already doing that.您不需要register.simple_tag(verified)行,因为@register装饰器已经这样做了。

However, you might consider a different approach to avoid additional processing in the template, assuming your user is coming from request.user ...但是,假设您的user来自request.user ...

@regsiter.assignment_tag(takes_context=True)
def check_user_is_verified(context):
    user = context['request'].user
    return user and user in vips

Then in your template:然后在您的模板中:

{% check_user_is_verified as is_verified %}
{% if is_verified %}
    {# whatever #}
{% endif %}

By leveraging an assignment tag, you can check if the user is verified once, and leverage the context variable you assign instead of having to perform the same list processing each time.通过利用分配标签,您可以检查用户是否经过一次验证,并利用您分配的上下文变量,而不必每次都执行相同的列表处理。

Another alternative is to use a cached property on a custom User object, or a "Profile" model that is linked to your User model via a OneToOneField.另一种选择是在自定义用户对象上使用缓存属性,或通过 OneToOneField 链接到用户模型的“配置文件”模型。

from django.utils.functional import cached_property

class Profile(models.Model):
    user = models.OneToOneField(User)

    @cached_property
    def is_verified(self):
        # get the list of vips here
        return self.user in vips

If your list of vips changes, just clear the cache key, which you could do via a signal or a Celery task, etc:如果您的 vips 列表发生变化,只需清除缓存键,您可以通过信号或 Celery 任务等执行此操作:

del profile_instance.is_verified

Now you have a very efficient property you can check anywhere in your code.现在您拥有了一个非常有效的属性,您可以在代码中的任何位置进行检查。 My preference tends to be fat models, skinny views and dumb templates.我的偏好往往是胖模型、瘦视图和愚蠢的模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM