zoukankan      html  css  js  c++  java
  • Python-S9——Day82-CRM项目实战

    1、权限的概念;

    2、RBAC的设计;

    3、注册登录用户所有权限到session中;

    4、权限的校验;

    5、基于中间件的权限校验;

    1、权限的概念;

    1.1 项目与应用;

    • Project
    • App

    1.2 什么是权限?一个URL就是一个权限;

      1.2.1 who what how  <------>True or False

      1.2.2 表相关,如UserInfo、Permission、UserInfo_Permission;

      1.2.3 管理员权限,比如腾旭视频的VIP会员,这个世界上权限无处不在;

      1.2.4 应用范围最广泛;

      1.2.5 Who、What、How------>True Or Flase

    2、RBAC的设计;

    2.1 不同的角色设置不同的权限;

    2.2 新增一张Role(角色表);

    • UserInfo
    • Role
    • Permission

    2.3 rbac(Role base access control)

    3、注册登录用户所有权限到session中;

    3.1 基于rbac/models.py生成关系表;

    from django.db import models
    
    
    # Create your models here.
    
    class User(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        roles = models.ManyToManyField(to="Role")
    
        def __str__(self):
            return self.name
    
    
    class Role(models.Model):
        title = models.CharField(max_length=32)
        permissions = models.ManyToManyField(to="Permission")
    
        def __str__(self):
            return self.title
    
    
    class Permission(models.Model):
        title = models.CharField(max_length=32)
        url = models.CharField(max_length=32)
    
        def __str__(self):
            return self.title

    2、进行数据库迁移操作;

    python manage.py makemigrations
    python migrate

    3、在rbac/admin.py中进行register注册操作;

    from django.contrib import admin
    
    # Register your models here.
    from .models import *
    
    admin.site.register(User)
    admin.site.register(Role)
    admin.site.register(Permission)

    4、进行超级用户的创建cuixiaozhao;

    Microsoft Windows [版本 10.0.17134.1]
    (c) 2018 Microsoft Corporation。保留所有权利。
    
    (venv) C:UsersTQTL911PycharmProjectss9day82_rbac>python manage.py startapp rbac
    
    (venv) C:UsersTQTL911PycharmProjectss9day82_rbac>python manage.py makemigrations
    Traceback (most recent call last):
      File "manage.py", line 15, in <module>
        execute_from_command_line(sys.argv)
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangocoremanagement\__init__.py", line 381, in execute_from_command_line
        utility.execute()
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangocoremanagement\__init__.py", line 375, in execute
        self.fetch_command(subcommand).run_from_argv(self.argv)
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangocoremanagementase.py", line 316, in run_from_argv
        self.execute(*args, **cmd_options)
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangocoremanagementase.py", line 350, in execute
        self.check()
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangocoremanagementase.py", line 379, in check
        include_deployment_checks=include_deployment_checks,
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangocoremanagementase.py", line 366, in _run_checks
        return checks.run_checks(**kwargs)
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangocorechecks
    egistry.py", line 71, in run_checks
        new_errors = check(app_configs=app_configs)
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangocorechecksurls.py", line 40, in check_url_namespaces_unique
        all_namespaces = _load_all_namespaces(resolver)
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangocorechecksurls.py", line 57, in _load_all_namespaces
        url_patterns = getattr(resolver, 'url_patterns', [])
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangoutilsfunctional.py", line 37, in __get__
        res = instance.__dict__[self.name] = self.func(instance)
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangourls
    esolvers.py", line 533, in url_patterns
        patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangoutilsfunctional.py", line 37, in __get__
        res = instance.__dict__[self.name] = self.func(instance)
      File "C:UsersTQTL911PycharmProjectss9day82_rbacvenvlibsite-packagesdjangourls
    esolvers.py", line 526, in urlconf_module
        return import_module(self.urlconf_name)
      File "C:Program FilesPython36libimportlib\__init__.py", line 126, in import_module
        return _bootstrap._gcd_import(name[level:], package, level)
      File "<frozen importlib._bootstrap>", line 994, in _gcd_import
      File "<frozen importlib._bootstrap>", line 971, in _find_and_load
      File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
      File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
      File "<frozen importlib._bootstrap_external>", line 678, in exec_module
      File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
      File "C:UsersTQTL911PycharmProjectss9day82_rbacs9day82_rbacurls.py", line 18, in <module>
        from app01 import views
      File "C:UsersTQTL911PycharmProjectss9day82_rbacapp01views.py", line 5
        user_id = request.
                         ^
    SyntaxError: invalid syntax
    
    (venv) C:UsersTQTL911PycharmProjectss9day82_rbac>python manage.py makemigrations
    Migrations for 'app01':
      app01migrations001_initial.py
        - Create model User
    Migrations for 'rbac':
      rbacmigrations001_initial.py
        - Create model Permission
        - Create model Role
        - Create model User
    
    (venv) C:UsersTQTL911PycharmProjectss9day82_rbac>python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, app01, auth, contenttypes, rbac, sessions
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying admin.0003_logentry_add_action_flag_choices... OK
      Applying app01.0001_initial... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0002_alter_permission_name_max_length... OK
      Applying auth.0003_alter_user_email_max_length... OK
      Applying auth.0004_alter_user_username_opts... OK
      Applying auth.0005_alter_user_last_login_null... OK
      Applying auth.0006_require_contenttypes_0002... OK
      Applying auth.0007_alter_validators_add_error_messages... OK
      Applying auth.0008_alter_user_username_max_length... OK
      Applying auth.0009_alter_user_last_name_max_length... OK
      Applying rbac.0001_initial... OK
      Applying sessions.0001_initial... OK
    
    (venv) C:UsersTQTL911PycharmProjectss9day82_rbac>python manage.py createsuperuser
    Username (leave blank to use 'tqtl911'): cuixiaozhao
    Email address: tqtl@tqtl.org
    Password:
    Password (again):
    This password is too common.
    Bypass password validation and create user anyway? [y/N]: y
    Superuser created successfully.
    
    (venv) C:UsersTQTL911PycharmProjectss9day82_rbac>

    5、启动Django项目,进行admin后台访问;

    6、分别通过前端页面,进行Permission、Role、User的添加操作;

    7、在settings.py中添加INSTALLED_APPS并配置urls.py;

    """s9day82_rbac URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/2.1/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  path('', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.urls import include, path
        2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    """
    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('users/', views.users),
        path('^/users/add', views.add_user),
        path('^roles/', views.roles),
        path('login/', views.login),
    ]

    8、编写视图函数views.py;

    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    from rbac.models import *
    
    
    def users(request):
        user_list = User.objects.all()
        return render(request, "users.html", locals())
    
    
    def add_user(request):
        return HttpResponse("add_user")
    
    
    def roles(request):
        user_list = User.objects.all()
        return render(request, "users.html", locals())
    
    
    def login(request):
        if request.method == "POST":
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
            user_obj = User.objects.filter(name=user, pwd=pwd).first()
            if user_obj:
                # 在session中注册用户的ID;
                request.session["user_id"] = user.pk
    
                '''
                在session中注册权限列表;
                '''
                # #查询当前登录用的所有角色;
                # ret = user_obj.roles.all()
                # print(ret)#<QuerySet [<Role: 保洁>, <Role: 销售>]>
                # 查询当前登录用的所有权限;
    
                # ret = user_obj.roles.all().values("title")
                # ret = user_obj.roles.all().values("title",
                #                                  "permissions__url")  # <QuerySet [{'title': '保洁', 'permissions__url': '/users/'}, {'title': '销售', 'permissions__url': '/users/'}, {'title': '销售', 'permissions__url': '/users/add'}]>
    
                permissions = user_obj.roles.all().values(
                    "permissions__url").distinct()  # <QuerySet [{'permissions__url': '/users/'}, {'permissions__url': '/users/add'}]>
                permission_list = []  # 定义一个空列表;
                for item in permissions:
                    permission_list.append(item["permissions__url"])
                print(permission_list)  # ['/users/', '/users/add']
                request.session["permission_list"] = permission_list
                '''
                values:
                temp = []
                for role in user.roles.all(): #[<Role:保洁>,<Role:销售>]
                temp.append({
                "title":role.title,#<QuerySet [{'title': '保洁'}, {'title': '销售'}]>
                })
                '''
                return HttpResponse("登录成功!")
    
        return render(request, "login.html")

    9、编写templates下的login.html;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style type="text/css">
    
        </style>
    </head>
    <body>
    <h4>登录页面</h4>
    <form action="" method="post">
        {% csrf_token %}
        用户名: <input type="text" name="user"></input>
        密码: <input type="password" name="pwd"></input>
        <input type="submit">
    </form>
    </body>
    </html>

     users.html;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style type="text/css">
    
        </style>
    </head>
    <body>
    <ul>
        <h4>用户列表</h4>
        {% for user in user_list %}
            <p>{{ user }}</p>
        {% endfor %}
    
    </ul>
    </body>
    </html>

    4、权限的校验;

    1、一个含有正则表达式的URL就是一个权限;

    2、permission = “^%s$”%permission;

    urls.py;

    """s9day82_rbac URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/2.1/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  path('', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.urls import include, path
        2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    """
    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('users/', views.users),
        path('users/add', views.add_user),
        path('roles/', views.roles),
        path('login/', views.login),
    ]

    views.py;

    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    from rbac.models import *
    
    
    def users(request):
        user_list = User.objects.all()
        return render(request, "users.html", locals())
    
    
    def add_user(request):
        permission_list = request.session[
            "permission_list"]  # ['/users/', '/users/add', '/users/delete/(\d+)', 'users/edit(\d+)']
        current_path = request.path_info
        if current_path in permission_list:
            pass
    
        return HttpResponse("add_user")
    
    
    def roles(request):
        user_list = User.objects.all()
        return render(request, "users.html", locals())
    
    
    def login(request):
        if request.method == "POST":
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
            user_obj = User.objects.filter(name=user, pwd=pwd).first()
            if user_obj:
                # 在session中注册用户的ID;
                request.session["user_id"] = user_obj.pk
    
                '''
                在session中注册权限列表;
                '''
                # #查询当前登录用的所有角色;
                # ret = user_obj.roles.all()
                # print(ret)#<QuerySet [<Role: 保洁>, <Role: 销售>]>
                # 查询当前登录用的所有权限;
    
                # ret = user_obj.roles.all().values("title")
                # ret = user_obj.roles.all().values("title",
                #                                  "permissions__url")  # <QuerySet [{'title': '保洁', 'permissions__url': '/users/'}, {'title': '销售', 'permissions__url': '/users/'}, {'title': '销售', 'permissions__url': '/users/add'}]>
    
                permissions = user_obj.roles.all().values(
                    "permissions__url").distinct()  # <QuerySet [{'permissions__url': '/users/'}, {'permissions__url': '/users/add'}]>
                permission_list = []  # 定义一个空列表;
                for item in permissions:
                    permission_list.append(item["permissions__url"])
                print(permission_list)  # ['/users/', '/users/add']
                request.session["permission_list"] = permission_list
                '''
                values:
                temp = []
                for role in user.roles.all(): #[<Role:保洁>,<Role:销售>]
                temp.append({
                "title":role.title,#<QuerySet [{'title': '保洁'}, {'title': '销售'}]>
                })
                '''
                return HttpResponse("登录成功!")
    
        return render(request, "login.html")

    test.py;

    from django.test import TestCase
    
    # Create your tests here.
    
    l = ['/users/', '/users/add', '/users/delete/(\d+)', 'users/edit(\d+)']
    c_path = "users/delete/9"
    
    import re
    
    flag = False
    for permission in l:
        permission = "^%s$"%permission
        ret = re.match("", c_path)
        if ret:
            flag = True
            break
    if flag:
        print("Success!")

    5、基于中间件的权限校验;

    1、创建表关系:

    2、基于admin录入数据;

    3、 登录校验:

    4、校验权限(中间件的应用)

    5、自定义中间件,并在settings.py中配置;

    6、配置白名单valid_url_list;

    settings.py;

    """
    Django settings for s9day82_rbac project.
    
    Generated by 'django-admin startproject' using Django 2.1.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/2.1/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/2.1/ref/settings/
    """
    
    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = 'lp7xgai1mm6&w^!2jj3gj6j*fd)0^%nzks)w4t$a89s@c&zwt_'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
        'rbac.apps.RbacConfig',
    ]
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'rbac.service.rbac.ValidPermission',
    ]
    
    ROOT_URLCONF = 's9day82_rbac.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 's9day82_rbac.wsgi.application'
    
    # Database
    # https://docs.djangoproject.com/en/2.1/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    # Password validation
    # https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    # Internationalization
    # https://docs.djangoproject.com/en/2.1/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/2.1/howto/static-files/
    
    STATIC_URL = '/static/'

    models.py;

    from django.db import models
    
    
    # Create your models here.
    
    class User(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        roles = models.ManyToManyField(to="Role")
    
        def __str__(self):
            return self.name
    
    
    class Role(models.Model):
        title = models.CharField(max_length=32)
        permissions = models.ManyToManyField(to="Permission")
    
        def __str__(self):
            return self.title
    
    
    class Permission(models.Model):
        title = models.CharField(max_length=32)
        url = models.CharField(max_length=32)
    
        def __str__(self):
            return self.title

    urls.py;

    """s9day82_rbac URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/2.1/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  path('', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.urls import include, path
        2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    """
    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('users/', views.users),
        path('users/add', views.add_user),
        path('roles/', views.roles),
        path('login/', views.login),
    ]

    views.py;

    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    from rbac.models import *
    from rbac.service.permissions import *
    import re
    
    
    def users(request):
        user_list = User.objects.all()
        return render(request, "users.html", locals())
    
    
    def add_user(request):
    
    
        return HttpResponse("add_user")
    
    
    def roles(request):
        #写个中间件;
    
    
        role_list = Role.objects.all()
        return render(request, "roles.html", locals())
    
    
    def login(request):
        if request.method == "POST":
            user = request.POST.get("user")
            pwd = request.POST.get("pwd")
            user_obj = User.objects.filter(name=user, pwd=pwd).first()
            if user_obj:
                # 在session中注册用户的ID;
                request.session["user_id"] = user_obj.pk
    
                '''
                在session中注册权限列表;
                '''
                # #查询当前登录用的所有角色;
                # ret = user_obj.roles.all()
                # print(ret)#<QuerySet [<Role: 保洁>, <Role: 销售>]>
                # 查询当前登录用的所有权限;
    
                # ret = user_obj.roles.all().values("title")
                # ret = user_obj.roles.all().values("title",
                #                                  "permissions__url")  # <QuerySet [{'title': '保洁', 'permissions__url': '/users/'}, {'title': '销售', 'permissions__url': '/users/'}, {'title': '销售', 'permissions__url': '/users/add'}]>
    
                #查询当前登录用户的所有权限;
                initial_session(user_obj,request)
                '''
                values:
                temp = []
                for role in user.roles.all(): #[<Role:保洁>,<Role:销售>]
                temp.append({
                "title":role.title,#<QuerySet [{'title': '保洁'}, {'title': '销售'}]>
                })
                '''
                return HttpResponse("登录成功!")
    
        return render(request, "login.html")

    permissions.py;

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    # __Author__:TQTL911
    # Version:python3.6.6
    # Time:2018/8/29 22:28
    
    def initial_session(user_obj,request):
        permissions = user_obj.roles.all().values(
            "permissions__url").distinct()  # <QuerySet [{'permissions__url': '/users/'}, {'permissions__url': '/users/add'}]>
        permission_list = []  # 定义一个空列表;
        for item in permissions:
            permission_list.append(item["permissions__url"])
        print(permission_list)  # ['/users/', '/users/add']
        request.session["permission_list"] = permission_list

    rbac.py;

    #!/usr/bin/env python3
    # -*- coding:utf-8 -*-
    # __Author__:TQTL911
    # Version:python3.6.6
    # Time:2018/8/29 22:03
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse, redirect
    import re
    
    
    class ValidPermission(MiddlewareMixin):
        def process_request(self, request):
            # 当前访问的路径;
            current_path = request.path_info
            # 校验权限,检查是否属于白名单;
            varlid_url_list = ["/login/", "/reg/", "/admin/.*"]
            for valid_url in varlid_url_list:
                ret = re.match(valid_url, current_path)
                if ret:
                    return None
            # 校验是否登录;
            user_id = request.session.get("user_id")
            if not user_id:
                return redirect("/login/")
    
            if current_path in varlid_url_list:
                return None
    
            # 权限的校验;
            permission_list = request.session.get("permission_list",
                                                  [])  # ['/users/', '/users/add', '/users/delete/(\d+)', 'users/edit(\d+)']
            flag = False
            for permission in permission_list:
                permission = "^%s$" % permission
                ret = re.match(permission, current_path)
                if ret:
                    flag = True
                    break
            if not flag:
                return HttpResponse("没有访问权限")
            return None

    tests.py;

    from django.test import TestCase
    
    # Create your tests here.
    
    l = ['/users/', '/users/add', '/users/delete/(\d+)', 'users/edit(\d+)']
    c_path = "users/delete/9"
    
    import re
    
    flag = False
    for permission in l:
        permission = "^%s$"%permission
        ret = re.match("", c_path)
        if ret:
            flag = True
            break
    if flag:
        print("Success!")

    users.html;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style type="text/css">
    
        </style>
    </head>
    <body>
    <ul>
        <h4>用户列表</h4>
        {% for user in user_list %}
            <p>{{ user }}</p>
        {% endfor %}
    
    </ul>
    </body>
    </html>

    roles.html;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>roles</title>
        <style type="text/css">
    
        </style>
    </head>
    <body>
    <ul>
        <h4>角色列表</h4>
        {% for role in role_list %}
            <p>{{ role }}</p>
        {% endfor %}
    
    </ul>
    </body>
    </html> 

    5 权限按钮控制的简单形式;

    5.1 

    6 权限菜单显示

    7 Django的路径自动添加问题

    7.1 settings.py中添加APPEND_SLASH = FALSE,默认为True,解决URL末尾路径斜杠自动添加的问题;

    8 原生form实现增删改查

    9 modelform实现增删改查

  • 相关阅读:
    C# 中的EventHandler
    Leetcode:Combinations 组合
    Leetcode:Minimum Path Sum
    [LeetCode] Container With Most Water
    一个数n的最少可以由多少个数的平方和组成
    单链表的归并排序
    几个常用的操作系统进程调度算法(转)
    字符串的最长重复子串(转)
    linux静态链接库与动态链接库详解
    简易的hashtable实现
  • 原文地址:https://www.cnblogs.com/tqtl911/p/9555276.html
Copyright © 2011-2022 走看看