django:在普通django项目中设置网页访问权限

一,准备知识

可以参考django:用户、用户组及权限设置,这篇文章介绍了用户权限相关的一些知识,先根据该内容了解设置用户权限的原理与使用方法。

二,功能实现

1, 注册功能

实现用户注册功能。为了快速实现总体功能,就简化地在注册时赋予页面访问权限。

def registerView(request):
    userLogin = False
    if request.method == 'POST':
        user = MyUserCreationForm(request.POST)
        if user.is_valid():
            user.save()
            tips = '注册成功'
            # 添加权限
            u = user.instance
            p = Permission.objects.filter(codename='vip_myuser')[0]
            u.user_permissions.add(p)
            return redirect(reverse('user:login'))
        else:
            tips = '注册失败'
    user = MyUserCreationForm()
    return render(request, 'user.html', locals())
  • 自定义表单类MyUserCreationForm,继承自UserCreationForm,实现表单注册。
  • 对初测成功的用户赋予vip权限,本质上就是对用户表与用户权限表设置多对多的数据关系。
  • 使用上下文传递提示信息与页面功能判断信息。

2,登录功能

对输入的登陆信息进行验证,成功则进入用户中心,否则要重新输入信息。

def loginView(request):
    tips = '请登录'
    userLogin = True
    if request.method == 'POST':
        u = request.POST.get('username', '')
        p = request.POST.get('password1', '')
        if MyUser.objects.filter(username=u):
            user = authenticate(username=u, password=p)
            if user:
                if user.is_active:
                    # 登录当前用户
                    login(request, user)
                return redirect(reverse('user:info'))
            else:
                tips = '账号密码错误,请重新输入'
        else:
            tips = '用户不存在,请注册'
    user = MyUserCreationForm()
    return render(request, 'user.html', locals())
  • 获取登录信息以进行验证。
  • 使用内置的login()方法完成登录。
  • 使用上下文传递提示信息与页面功能判断信息。

3,用户中心

在执行进入VIP网页操作之前,先验证该用户是否有权限。
用户中心进行极简的内容展示。

@login_required(login_url='/login.html')
@permission_required(perm='user.vip_myuser', login_url='/login.html')
def infoView(request):
    return render(request, 'info.html', locals())
  • 使用@login_required()装饰器判断用户是否已登录。
  • 使用@permission_required()装饰器判断用户是否拥有正确的权限。

4,注销功能

从用户中心退出登录。

def logoutView(request):
    logout(request)
    return redirect(reverse('user:login'))
  • 使用内置的logout()方法完成注销。

1~4完整代码:

from django.shortcuts import render, redirect
from django.shortcuts import reverse
from .models import MyUser
from .form import MyUserCreationForm
from django.contrib.auth.models import Permission
from django.contrib.auth import login, authenticate, logout
from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import permission_required


# 用户注册
def registerView(request):
    userLogin = False
    if request.method == 'POST':
        user = MyUserCreationForm(request.POST)
        print('user:\n', user)
        if user.is_valid():
            user.save()
            tips = '注册成功'
            u = user.instance
            p = Permission.objects.filter(codename='vip_myuser')[0]
            u.user_permissions.add(p)
            return redirect(reverse('user:login'))
        else:
            tips = '注册失败'
    user = MyUserCreationForm()
    return render(request, 'user.html', locals())

# 用户登录
def loginView(request):
    tips = '请登录'
    userLogin = True
    if request.method == 'POST':
        u = request.POST.get('username', '')
        p = request.POST.get('password1', '')
        if MyUser.objects.filter(username=u):
            user = authenticate(username=u, password=p)
            if user:
                if user.is_active:
                    # 登录当前用户
                    login(request, user)
                return redirect(reverse('user:info'))
            else:
                tips = '账号密码错误,请重新输入'
        else:
            tips = '用户不存在,请注册'
    user = MyUserCreationForm()
    return render(request, 'user.html', locals())

# 退出登录
def logoutView(request):
    logout(request)
    return redirect(reverse('user:login'))

# 用户中心
@login_required(login_url='/login.html')
@permission_required(perm='user.vip_myuser', login_url='/login.html')
def infoView(request):
    return render(request, 'info.html', locals())

5,模板文件

user.html:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="utf-8">
    <title>用户管理</title>
    <link rel="stylesheet" href="https://unpkg.com/mobi.css/dist/mobi.min.css">
</head>
<body>
<div class="flex-center">
    <div class="container">
    <div class="flex-center">
    <div class="unit-1-2 unit-1-on-mobile">
        {% if userLogin %}
            <h1>用户登录</h1>
        {% else %}
            <h1>用户注册</h1>
        {% endif %}
        {% if tips %}
            <div>{{ tips }}</div>
        {% endif %}
        <form class="form" action="" method="post">
            {% csrf_token %}
            <div>用户名:{{ user.username }}</div>
            <div>密  码:{{ user.password1 }}</div>
            {% if not userLogin %}
            <div>密码确认:{{ user.password2 }}</div>
            <div>邮  箱:{{ user.email }}</div>
            <div>手机号:{{ user.mobile }}</div>
            <div>Q Q 号:{{ user.qq }}</div>
            <div>微信号:{{ user.weChat }}</div>
            {% endif %}
            <button type="submit" class="btn btn-primary btn-block">确 认</button>
        </form>
    </div>
    </div>
    </div>
</div>
</body>
</html>


info.html:
{% load static %}
<title>用户中心</title>
<link rel="stylesheet" href="{% static "css/common.css" %}">
<link rel="stylesheet" href="{% static "css/home.css" %}">
</head>
<body class="member">
    <div class="mod_profile js_user_data">
        <div class="section_inner">
	        {#user由模型MyUser实例化#}
            {% if user.is_authenticated %}
            <div class="profile__cover_link">
                <img src="{% static "image/user.png" %}" class="profile__cover">
            </div>
            <h1 class="profile__tit">
                <span class="profile__name">{{ user.username }}</span>
            </h1>
            {#perms是模型Permission实例化对象#}
	        {% if perms.user.vip_myuser %}
                <div class="profile__name">你好,尊贵的VIP会员</div>
            {% endif %}
                <a href="{% url 'user:logout' %}" style="color:#ea4907; font-size: medium">退出登录</a>
            {% endif %}
        </div>
    </div>
</body>
</html>
  • infoView视图是没有定义模板上下文user与perms的,它们在解析模板上下文的过程中产生:
    1,先在settings.py中查看模板上下文处理器的配置。
    2,解析模板时django依次运行context_processors中定义的处理程序,当执行完django.contrib.auth.context_processors.auth时产生user与perms并传入模板上下文,可以看看django.contrib.auth.context_processors.auth的源码。
MyDjango/settings.py:
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [ # 这里定义了模板处理器集合,django会顺序执行。
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',	# user与perms由这里产生
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

关于上下文处理器:

***django.template.context_processors.request:增加一个request变量。正是因为有了这个上下文处理器,我们才能在任意模板中从request获取数据。
***django.contrib.auth.context_processors.auth:使用Django内置的认证系统,这个上下文处理器会增加我们所需要的user和perms,下面是django.contrib.auth.context_processors.auth的源码:
	def auth(request):
	    """
	    Return context variables required by apps that use Django's authenticationsystem.
	    If there is no 'user' attribute in the request, use AnonymousUser (from django.contrib.auth).
	    """
	    if hasattr(request, 'user'):
	        user = request.user
	    else:
	        from django.contrib.auth.models import AnonymousUser
	        user = AnonymousUser()
	
	    return {
	        'user': user,
	        'perms': PermWrapper(user),
	    }
***django.contrib.messages.context_processors.messages:增加messages变量。可以通过它来存放一些我们需要返回的错误信息。

6,运行

在这里插入图片描述

后面会出一个使用DRF实现权限管理的网站VIP功能,等着吧~~

  • 2
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值