First, the rear end portion
1. models Design
Implementation: the specific roles have access to a specific url path, roles associated with the user, in order to control user access.
Such as: Administrator: access to all of the url address, associate administrator armor, the armor has access to all url address, the average user: only have access to view the data (see page one) of the url address, associate general user B , B will only have normal user permissions
2.models achieve
class Permission(models.Model): url = models.CharField(max_length=64, verbose_name='权限') title = models.CharField(max_length=32, verbose_name='标题') def __str__(self): return self.title class Meta: verbose_name_plural = '权限管理' class Role(models.Model): name = models.CharField(max_length=32, verbose_name='角色') permissions = models.ManyToManyField(Permission, verbose_name='角色拥有的权限', blank=True) def __str__(self): return self.name class Meta: verbose_name_plural = '角色管理' class User(models.Model): username = models.CharField(max_length=32, verbose_name='用户名', unique=True) password = models.CharField(max_length=32, verbose_name='密码') roles = models.ManyToManyField(Role, verbose_name='User role ' , blank = True) DEF __str__ (Self): return self.username class Meta -: verbose_name_plural = ' User Manager '
3. The successful landing of the user's permissions (url address) is written in the session
from rbac import models from django.shortcuts import redirect, render, HttpResponse from django.conf import settings def login(request): if request.method == 'POST': username = request.POST.get('username') password = request.POST.get('password') obj = models.User.objects.filter(username=username, password=password).first() if notobj: error = ' user name or password is incorrect ' return the render (Request, ' login.html ' , about locals ()) # get permissions information permission = obj.roles.all () filter (permissions__url__isnull = False) .values (. ' permissions__url ' , ' permissions__title ' , ) .distinct () # get a list of logged-on user permissions (url address that can be accessed) request.session [ ' permission ' ] = list(permission) request.session['is_login'] = 1 return redirect('index') return render(request, 'login.html', locals())
4. white list and the list of free certification
# Whitelist: without logging in, you can access the path WHITE_LIST = [ r ' / the Login / ' , r ' ^ / ADMIN / ' , ] # authentication-free list after a user login can access the url PUBLIC_LIST = [ r ' / index / ' , ]
5. Obtain permission rights (url address list) request.session in from middleware
from django.utils.deprecation Import MiddlewareMixin from django.conf Import Settings from django.shortcuts Import redirect, HttpResponse Import Re class AuthMiddleware (MiddlewareMixin): DEF process_request (Self, Request): url = request.path_info # current page url address # white list: log in, register, ADMIN for i in settings.WHITE_LIST: # WHITE_LIST is configured in settings.py file address whitelist IF re.match (i, url): return # login authentication = request.session.get is_login ( ' is_login ' ) IF is_login = 1! : return redirect ( ' the Login ' ) # address after login authentication-free accessible to everyone, such as: background Home for i in settings.PUBLIC_LIST: IF Re .match (i, url): return # authority to verify that all of our rights (url address list) in the login function currently logged in user are placed into the session, out here and the current url address to match. = request.session.get permission ( ' permission ' ) for I in permission: IFre.match (R & lt ' ^ {} $ ' .format (I [ ' URL ' ]), URL): return return the HttpResponse ( ' without permission, please contact the administrator! ' )
Second, the front end portion
6. custom template tags, rendering data
Note: template tag storage directory must be tamplatetags
# - * - Coding: UTF-. 8 - * - # __author__ = "Maple" from Django Import Template from django.conf Import Settings Import Re Register = template.Library () @ register.inclusion_tag ( ' menu_tag.html ' ) # menu_tag this function is rendered with a template when .html file is part of the label DEF the MENU (Request): "" " when the current url address menu_list the url address to be able to match, to menu_list in to add match to address a key-value pair { "class": "Active"} "" " URL = Request. PATH_INFO # added to activate the style forI in menu_list: IF re.match (F ' ^ {I [ "URL"]} $ ' , URL): I [ ' class ' ] = ' Active ' BREAK return { ' menu_list ' : menu_list} # menu_list data format such as: # [{ 'url': '/ Customer / List /'}, { 'url': '/ Customer / the Add /'},] # If the current url address: / customer / list / when # is menu_list in data becomes: # [{ 'URL': '/ Customer / List /', "class": "Active"}, { 'URL': '/ Customer / the Add /'},]
my_tags file label content rendered by the decorator
<div class="static-menu"> {% for menu in menu_list %} <a href="{{ menu.url}}" class="{{menu.class}}">{{ menu.title}}</a> {% endfor %} </div>
7. Application of custom tags
... <div class="left-menu"> <div class="menu-body"> {% load my_tags %} {% menu request %} </div> ...