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

    • 01 上节回顾
    • 02 后台管理布局
    • 03 按钮权限控制的简单形式
    • 04 修改表结构
    • 05 重构数据结构
    • 06 限制权限颗粒度

    01 上节回顾

    1.1 项目的组织架构;

    1.2 项目组件的版本说明;

      使用的是Django1.11.1与最新的Django有区别,请注意。另外Pycharm创建的Django项目一般都是最新的,2018版本Pycharm自带virtualenv环境,无需个人再次安装。如需执行Django版本,可在本机的Python解释器环境下,pip install django=="1.11.1",然后通过Pycharm创建Django项目的时候指定一下内置的Python解释器,见下图。

    1.3 settings.py文件说明;

    自行配置TEMPLATES中的DIRS;

    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',
                ],
            },
        },
    ]

    settings.py

    """
    Django settings for s9day82_rbac project.
    
    Generated by 'django-admin startproject' using Django 1.11.1.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/1.11/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/1.11/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/1.11/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = '0s(th#!ewf^xik5n&bqkqqjadz#q*vt+!hq(kzk5*-!t6@^0^i'
    
    # 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',
    ]
    from django.middleware.security import SecurityMiddleware
    
    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/1.11/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/1.11/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/1.11/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/1.11/howto/static-files/
    
    STATIC_URL = '/static/'

    1.4 urls.py;

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

    1.5 views.py;

    import re
    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    from rbac.models import *
    from rbac.service.permissions 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):
        role_list = Role.objects.all()
        return render(request, "roles.html......", locals())
    
    
    def login(request):
        if request.method == "POST":
            user_obj = request.POST.get("user")
            pwd = request.POST.get("pwd")
            user = User.objects.filter(name=user_obj, pwd=pwd).first()
            if user:
                # #################在session中注册用户ID###########################;
                request.session["user_id"] = user.pk
                initial_session(user, request)
                '''
                此处的values()相当于:
                temp = []#定义一个空列表;
                for role in user.roles.all();#values属性,相当于循环该对象[<Role: 保洁>, <Role: 销售>]>
                    temp.append({
                    "title":role.title,
                    "permissions__url":role.permissions.all()
                    })
                '''
                return HttpResponse("登录成功!")
        return render(request, "login.html", locals())

    1.6 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

    1.7 templates模板文件;

    login.html 

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

    roles.html

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

    1.8 permissions.py

    def initial_session(user, request):
        # #################在session注册权限列表###########################;
        # 查询当前登录用户的所有角色;
        ret = user.roles.all()
        print("ret", ret)  # <QuerySet [<Role: 保洁>, <Role: 销售>]>
    
        # 查询当前用户的所有权限;
        permissions = user.roles.all().values(
            "permissions__url").distinct()  # ret_role <QuerySet [{'permissions__url': '/users/'},
        #  {'permissions__url': '/users/add'}]>
    
        # 进行数据的处理,生成列表;
        permission_list = []
        for item in permissions:
            permission_list.append(item["permissions__url"])
        print("permission_list", permission_list)  # permission_list ['/users/', '/users/add']
    
        request.session["permission_list"] = permission_list

    02 后台管理布局

    login.html;

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

    base.html;

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <style>
            .header {
                width: 100%;
                height: 60px;
                background-color: #336699;
    
            }
    
            .menu {
                background-color: bisque;
                position: fixed;
                top: 60px;
                bottom: 0;
                left: 0;
                width: 200px;
            }
    
            .content {
                position: fixed;
                top: 60px;
                bottom: 0;
                right: 0;
                left: 200px;
                overflow: auto;
                padding: 30px;
            }
        </style>
    </head>
    <body>
    <div class="header">
        <p>{{ user.name }}</p>
    </div>
    <div class="contain">
    
        <div class="menu">11</div>
        <div class="content ">
            {% block con %}
    
            {% endblock %}
        </div>
    
    </div>
    </body>
    </html>

    users.html;

    {% extends 'base.html' %}
    {% block con %}
        <h4>用户列表</h4>
        {% if per.add  %}
            <a href="/users/add/" class="btn btn-primary">添加用户</a>
        {% endif %}
    
        <table class="table table-bordered table-striped">
            <thead>
            <tr>
                <th>序号</th>
                <th>姓名</th>
                <th>角色</th>
                <th>操作</th>
            </tr>
            </thead>
            <tbody>
    
            {% for user in user_list %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ user.name }}</td>
                    <td>
                        {% for role in user.roles.all %}
                            {{ role.title }}
                        {% endfor %}
                    </td>
                    <td>
                        {% if per.delete %}
                            <a href="/users/delete/{{ user.pk }}" class="btn btn-danger">删除</a>
                        {% endif %}
                        {% if per.edit %}
                            <a href="" class="btn btn-info">编辑</a>
                        {% endif %}
                    </td>
                </tr>
            {% endfor %}
    
            </tbody>
        </table>
    {% endblock %}

    roles.html;

    {% extends 'base.html' %}
    {% block con %}
        <h4>角色列表</h4>
        {% if per.add %}
            <a href="" class="btn btn-primary">添加角色</a>
        {% endif %}
    
        <table class="table table-bordered table-striped">
            <tbody>
            {% for role in role_list %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ role.title }}</td>
                    <td>
                        <a href="/users/delete/{{ user.pk }}" class="btn btn-danger">删除</a>
                        <a href="" class="btn btn-info">编辑</a>
                    </td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
    {% endblock %}

    03 按钮权限控制的简单形式

    1、引入CDN的Bootstrap;

        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    04 修改表结构

    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)
        action = models.CharField(max_length=32, default="")
        group = models.ForeignKey("PermissionGroup", default=1)
    
        def __str__(self):
            return self.title
    
    
    class PermissionGroup(models.Model):
        title = models.CharField(max_length=32)
    
        def __str__(self):
            return self.title

    05 重构数据结构

    06 限制权限颗粒度

    settings.py; 

    """
    Django settings for s9day82_rbac project.
    
    Generated by 'django-admin startproject' using Django 1.11.1.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/1.11/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/1.11/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/1.11/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = '0s(th#!ewf^xik5n&bqkqqjadz#q*vt+!hq(kzk5*-!t6@^0^i'
    
    # 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',
    ]
    from django.middleware.security import SecurityMiddleware
    
    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/1.11/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/1.11/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/1.11/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/1.11/howto/static-files/
    
    STATIC_URL = '/static/'

    urls.py;

    """s9day82_rbac URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^users/$', views.users),
        url(r'^users/add', views.add_user),
        url(r'^users/delete/(d+)', views.del_user),
        url(r'^roles/', views.roles),
        url(r'^login/', views.login),
    ] 
  • 相关阅读:
    centos中pipelinedb安装及初步使用
    sqlalchemy 的操作
    存储引擎,索引,慢日志,权限管理
    python使用mysql
    mysql数据库查找数据的方法。
    mysql 数据库的基本操作
    epoll 数据库安装以及相关概念
    IO模型,非阻塞IO模型,select实现多路复用
    线程回调,线程中的队列,事件,greenlet模块,gevent模块,自定义补丁, 单线程实现并发,协程
    GIL全局解释器锁,线程池与进程池 同步异步,阻塞与非阻塞,异步回调
  • 原文地址:https://www.cnblogs.com/tqtl911/p/9582962.html
Copyright © 2011-2022 走看看