将在base中使用的上下文变量。html(Django)

时间:2022-03-12 23:58:43

I need a certain context variable in my base.html. This is to contain a set of usernames, e.g. [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.

在base.html中我需要一个特定的上下文变量。它包含一组用户名,例如[name1, name2, name3, name4]。如果登录用户的用户名是该列表的一部分,我将给予该用户一定的优惠待遇,并在导航条中显示一些内容。

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:

然后在基地。在上面添加了{% load verify %},然后:

{% 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项目。

1 个解决方案

#1


1  

You don't need the register.simple_tag(verified) line, as the @register decorator is already doing that.

您不需要register.simple_tag(已验证)行,因为@register decorator已经在这样做了。

However, you might consider a different approach to avoid additional processing in the template, assuming your user is coming from request.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:

如果您的vip列表发生变化,只需清除缓存键,您可以通过信号或芹菜任务等来完成:

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.

现在您有了一个非常有效的属性,您可以在代码中的任何地方进行检查。我的偏好倾向于肥胖的模特,瘦削的观点和愚蠢的模板。

#1


1  

You don't need the register.simple_tag(verified) line, as the @register decorator is already doing that.

您不需要register.simple_tag(已验证)行,因为@register decorator已经在这样做了。

However, you might consider a different approach to avoid additional processing in the template, assuming your user is coming from request.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:

如果您的vip列表发生变化,只需清除缓存键,您可以通过信号或芹菜任务等来完成:

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.

现在您有了一个非常有效的属性,您可以在代码中的任何地方进行检查。我的偏好倾向于肥胖的模特,瘦削的观点和愚蠢的模板。