Django根据不同的用户组部分限制内容

时间:2018-08-14 04:23:20

标签: python django

上周刚开始使用Django,我遇到了有关两种类型的用户(普通用户和VIP用户)以及如何限制普通用户查看VIP内容的问题。

我正在将Django与MySQL配合使用。我的网站不需要用户注册,但我将为他们提供用户名/密码。我通过Django管理员手动创建用户,并根据VIP或普通用户对其进行分组。我将上传内容(同样通过admin),并且我有一个布尔复选框,该复选框确定它是否是VIP内容。

我到目前为止所做的:

  1. 用户必须登录才能查看内容
  2. 登录后,VIP可以看到VIP内容,普通用户将无法看到VIP内容。

FAQ.html

{% extends 'base.html' %}
...skipping...
{% for faqs in fq reversed %}
<a href="{% url 'faq_topics' faqs.pk %}">{{ faqs.name }}</a>
{{ endfor }}

faq_topics.html

<h2>{{ faqs.name }}</h2>
<h6 style="padding: 20px 20px 20px 20px">{{ faqs.description|linebreaksbr }}</h6>

urls.py

urlpatterns = [
path('faq/', views.faq, name='faq'),
url(r'^faq/(?P<pk>\d+)/$', views.faq_topics, name='faq_topics'),]

views.py

def is_user(user):
    return user.groups.filter(name='User').exists()

def is_vip(user):
    return user.groups.filter(name='VIP').exists()

@login_required
@user_passes_test(is_user)
def faq(request):
    fq = FAQ.objects.filter(vip_only=False)
    return render(request, 'faq.html', {'fq':fq})

models.py

class FAQ(models.Model):

    name = models.CharField(max_length=30, unique=True)
    description = models.CharField(max_length=300)
    vip_only = models.BooleanField(default=False)

错误案例

输入3个FAQ条目,第一个被归类为VIP。

普通用户登录“常见问题”部分时,他/她只会看到2个内容

欢迎来到常见问题解答部分

  1. 127.0.0.1:8000/faq/3 /

  2. 127.0.0.1:8000/faq/2 /

但是,用户可以轻松地猜测faq / 1 /存在,并且当他们实际尝试时,他们也可以访问vip内容。

过去2天,我一直在网上搜索内容,我了解了如何使用@user_passes_test来限制用户和objects.filter(vip_only = False)来限制内容。

此外,我希望我的views.py控制两种用户的内容,但我尚未实现。如果有人可以教我如何在一个模板中实现“ 2个视图”,将不胜感激。

我已阅读,

show different content based on logged in user django

django - 2 views in one template

我的用户拆分解决方案

    @login_required
    def faq(request):
        '''user is separate using groups'''
        if request.user.is_superuser or request.user.groups.filter(name='VIP').exists():
            fq = FAQ.objects.all()
        else:
            fq = FAQ.objects.filter(vip_only=False)
        return render(request, 'faq.html', {'fq':fq})

1 个答案:

答案 0 :(得分:1)

您应该执行类似的操作

def faq(request):
    if request.user.is_superuser:
        fq = FAQ.objects.all()
    else:
        fq = FAQ.objects.filter(vip_only=False)
    return render(request, 'faq.html', {'fq':fq})

您还可以在模板中使用类似的方法进行处理:

{% if user.is_superuser %}
  #...show what you only want to show the superuser
{% endif %}

在您针对单个常见问题的方法中,执行以下操作:

def faq_topics(request, pk):
    faq_item=FAQ.objects.get(id=pk)
    if not request.user.is_superuser and not request.user.groups.filter(name='VIP').exists(): 
        if fqa_item.vip_only:
            return render(request, 'path_to_access_error_template', {'fq':faq_nr})
    return render(request, 'faq_item.html', {'fq':faq_nr})