分分钟开发一个Django项目,思路梳理

CRM系统开发,主要目标及步骤

  • 权限
  • stark组件
  • crm业务

第一部分:权限组件

1. 创建django project

2. 两个app

  • rbac,权限组件
  • web,销售管理系统

3. app:rbac

  • 将权限相关的表编写到此app的models.py中

    from django.db import models
    class Permission(models.Model):
    """
    权限表
    """
    title = models.CharField(verbose_name='标题', max_length=32)
    url = models.CharField(verbose_name='含正则的URL', max_length=128)
    
    def __str__(self):
        return self.title
    
    
    class Role(models.Model):
    """
    角色
    """
    title = models.CharField(verbose_name='角色名称', max_length=32)
    permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True)
    
    def __str__(self):
        return self.title
    
    
    class UserInfo(models.Model):
    """
    用户表
    """
    name = models.CharField(verbose_name='用户名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=64)
    email = models.CharField(verbose_name='邮箱', max_length=32)
    roles = models.ManyToManyField(verbose_name='拥有的所有角色', to='Role', blank=True)
    
    def __str__(self):
        return self.name
    

4. app:web

  • 将销售管理系统表写到此app的models.py中
  • 销售系统的业务相关代码:luffy_permission(示例二)

5. 两个app的整合

销售管理系统中的URL:
    客户管理
        客户列表:/customer/list/
        添加客户:/customer/add/
        删除客户:/customer/list/(?P<cid>\d+)/
        修改客户:/customer/edit/(?P<cid>\d+)/
        批量导入:/customer/import/
        下载模板:/customer/tpl/
    账单管理
        账单列表:/payment/list/
        添加账单:/payment/add/
        删除账单:/payment/del/(?P<pid>\d+)/
        修改账单:/payment/edit/<?P<pid>\d+/

5.1 基于admin进行权限信息的录入

5.2 基于admin进行权限和角色信息的分配

6. 快速完成一个基本权限控制

 1. 登录页面是否有权限访问。
 2. POST请求,用户登录检验是否合法。
 3. 获取当前用户相关的所有权限并放入session。
 4. 再次向服务端发起请求:http://www.xxx.com/xxx,后端编写中间件对用户当前访问的url进行权限的判断(是否在session中)

7. 功能的完善,将权限相关的功能放到rbac应用下,以便以后组件的应用。

a. 用户登录和权限初始化拆分
b. 配置文件应用
总结:6/7属于进行权限控制8

8. 动态菜单的功能

  • 一级菜单,如何实现动态显示菜单?

    a. 表结构修改
    b. 获取菜单信息并保存到session
    c. 模板中显示菜单信息(session)
    
  • 二级菜单

    a. session中存储的菜单信息结构:

    {
            1:{
                title:'信息管理',
                icon:'x1',
                children:[
                    {'title':'客户列表','url':'/customer/list/'},
                    {'title':'帐单列表','url':'/account/list/'},
                ]
            },
            2:{
                title:'用户信息',
                icon:'x1',
                children:[
                    {'title':'个人资料','url':'/userinfo/list/'},
                ]
            }
        }
    

    b. 数据库表结构的修改

     class Menu(models.Model):
         """
         菜单表
         """
         title = models.CharField(verbose_name='菜单名称', max_length=32)
         icon = models.CharField(verbose_name='图标', max_length=32)
    
         def __str__(self):
             return self.title
     class Permission(models.Model):
         """
         权限表
         """
         title = models.CharField(verbose_name='标题', max_length=32)
         url = models.CharField(verbose_name='含正则的URL', max_length=128)
    
         name = models.CharField(verbose_name='URL别名', max_length=32, unique=True)
    
         menu = models.ForeignKey(verbose_name='所属菜单', to='Menu', null=True, blank=True, help_text='null表示不是菜单;非null表示是二级菜单',on_delete=models.CASCADE)
    
         pid = models.ForeignKey(verbose_name='关联的权限', to='Permission', null=True, blank=True, related_name='parents',
                                 help_text='对于非菜单权限需要选择一个可以成为菜单的权限,用户做默认展开和选中菜单',on_delete=models.CASCADE)
    
         def __str__(self):
             return self.title
    

    c. 页面显示二级菜单

     	inclusion_tag中循环显示
     开发二级菜单:
    

9. 点击非菜单的权限时,默认选中或默认展开。

当点击某个不能成为菜单的权限时,指定一个可以成为菜单的权限,让其默认选中以及展开。

a. 数据库设计
b. 思路

  • 登录,做权限和菜单的初始化:

    • 获取菜单信息
    {
        1:{
            'title':'信息管理',
            'icon':'fa-camera-retro',
            'class':'',
            'children':[
                {'url':'/customer/list/','title':'客户列表',class='active'}  # 可以做菜单的权限ID
            ]
        }
        2:{
            'title':'用户管理',
            'icon':'fa-fire',
            'class':'hide',
            'children':[
                {'url':'/payment/list','title':'帐单列表'}
            ]
        }
    }
    
    • 获取权限信息
      [
          {'id':1,'url':'/customer/list/','pid':null}',           # 客户列表,可做菜单的
          {'id':2,'url':'/customer/add/','pid':1}',               # 添加客户,不可
          {'id':3,'url':'/customer/del/(?<cid>\d+)','pid':1}',    # 删除客户,不可
      ]
    
  • 再次来访问

    • 中间件进行权限的校验(根据权限信息)
      获取ID或PID(应该被选中的可以做菜单的权限ID)
  • 模板中使用inclusion_tagshengcheng动态菜单(根据菜单信息进行动态生成)

10. 路径导航

11. 权限力度控制到按钮级别

总结:

  • 权限控制
  • 动态菜单
  • 权限的分配

问题:以前你是如何做的权限分配?被某个用户分配一个角色?某个任分配某个权限。
答案:django admin进行录入

12. 权限分配

a. 角色管理

  • ModelForm
  • 根据 namespace 和 name 反向生成URL
  • 模板的查找顺序

b. 用户管理

  • ModelForm
    • 字段的自定制
    • 钩子方法
    • 错误提示(中文)
    • 重写__init__方法,统一给所有字段添加属性(form-control)
  • 根据 namespace 和 name 反向生成URL
  • 模板的查找顺序

c. 菜单和权限管理
视频讲解:

  • 一级
  • 二级
  • 权限

知识点:

  • 保留URL中的原搜索条件
  • 模板中整形转换成字符串 1|safe
  • ModelForm定制radio
  • ModelForm显示默认值
  • ModelForm save之前对其instance进行修改
  • BootStrapModelForm基类

d. 批量的权限操作

  • formset
    • 什么是formset?
      答:Form组件或ModelForm用于做一个表单验证。用于做多个表单验证的组件。
    • 应用场景?
      答:批量操作。
    • 如何实现用formset?
      答:见示例代码
  • 自动发现项目中的URL
    • 问题:给你一个项目,请帮我获取当前项目中都有哪些URL以及name rbac:permission_list
    • 实现思路。
    • 具体实现:见实例代码。
  • 权限的批量操作
  • 知识点
    • formset(ModelFormSet)
    • 自动发现项目中的URL
    • 唯一约束的错误信息

e. 分配权限

  • 展示用户、角色、权限信息
  • 选择用户、角色时,页面上的默认选项。
  • 角色和权限分配[保存]
  • 知识点的总结:
    • 数据类型设置引用

      menu_list=[
          {'id':1,'title':'菜单1'},
          {'id':2,'title':'菜单2'},
          {'id':3,'title':'菜单3'},
      ]
      
      menu_dict={}
      """
      menu_dict={
          1:{'id':1,'title':'菜单1'},
          2:{'id':2,'title':'菜单2'},
          3:{'id':3,'title':'菜单3'},
      }
      """
      
      for item in menu_list:
      munu_dict[item['id']]=item
      
      # menu_dict[2]['title']='666'
      
      menu_dict[2]['children']=[11,22]
      
      print(menu_list)
      

13. 编写使用文档(主机管理程序)

第二部分:stark组件

介绍:

stark组件,是一个帮助开发者快速实现数据库表的增删改查+。

目标:

10s中完成一张表的增删改查

前戏:

1. django项目启动时,自定义执行某个py文件。

django启动时,且在读取项目中路由之前执行某个py文件。
在任意app的apps.py中的Config类中定义ready方法,并调用
from django.apps import AppConfig
from django.utils.module_loading import autodiscover_modules

class App01Config(AppConfig):
    name = 'app01'

    def ready(self):
        autodiscover_modules('文件名')
django在启动时,就会去已注册的所有app的目录下找xxxx.py,并自动导入。
如果执行两次,是因为django内部自动重启导致:
python manage.py runserver 127.0.0.1:8000 --noreload
提示:
	如果xxxx.py执行的代码向"某个神奇的地方"放入了一些值,之后的路由加载时,可以去"某个神奇的地方"读取到原来设置的值.

2. 单例模式

单,一个
例,实例,对象。

通过利用Python模块导入的特性:在Python中,如果已经导入过的文件再次被重新导入时,python不在重新解释一遍,二十选择从内存中直接将原来的导入的值拿来用。
xxx.py
    class AdminSite(object):
        pass
    site=AdminSite()#为AdminSite类创建了一个对象(实例)
app.py
    import utils
    print(utils.site)

    import utils
    print(utils.site)
提示:
	如果以后存在一个单实例模式的对象,可以先在此对象中放入一个值,然后再在其他的文件中导入对象,通过对象再次将值获取到。

3. django路由分发的本质:include

方式一:

from django.conf.urls import url,include

urlpatterns=[
    url(r'^web/',include("app01.urls")),
]

方式二:

include函数主要返回有三个元素的元组。
from django.conf.urls import url,include
from app01 import urls
urlpatterns=[
    url(r'^web/',(urls,app_name,namespace)), # 第一个参数时urls文件对象,通过此对象可以获取urls.patterns获取分发的路由。
]
在源码内部,读取路由时:
	如果第一个参数有:urls.patterns属性,那么子路由就从该属性中获取。
	如果第一个参数无:urls.patterns属性,那么子路由就是第一个参数。

方式三:

urlpatterns=[
   url(r'^web/',([

   ],app_name,namespace)), #第一个参数是urls文件对象,通过此对象可以获取urls.patterns获取分发的路由。
]
示例:pre_luffy_stark.zip

开始:

1. 创建django project

2. 创建基础的业务表:

            app01/models.py
                部门表
                用户表
            app02/models.py
                主机表

3. 对以上的三张表做增删改查

a. 分析

  • 为每张表创建4个url

  • 为每张表创建4个视图函数

     app01/models.py
         Depart
             /app01/depart/list/
             /app01/depart/add/
             /app01/depart/edit/(\d+)/
             /app01/depart/del/(\d+)/
         userinfo
             /app01/userinfo/list/
             /app01/userinfo/add/
             /app01/userinfo/edit/(\d+)/
             /app01/userinfo/del/(\d+)/
     app02/models.py
         Host
             /app01/host/list/
             /app01/host/add/
             /app01/host/edit/(\d+)/
             /app01/host/del/(\d+)/
    

b. 为app中的每个model类自动创建URL及相关试图函数

  • 动态生成URL
  • 将试图提取到基类
  • URL分发扩展 & 后缀
  • 为URL设置别名
  • 为URL设置别名

c. 定制页面显示的列

  • 基本列表页面列的定制
  • 未定义list_display字段的页面,默认显示对象
  • 为页面显示的列预留一个钩子函数
  • 为页面提供自定义显示的函数
  • 应用

d. 应用模板样式(BootStrap)
e. 列表页面添加分页的功能
f. 添加

  • 如何显示添加按钮
  • 添加按钮的URL
  • 添加页面进行添加数据

g. 编辑

  • 编辑按钮(删除按钮)
  • 页面操作

h. 删除

4. 其他常用功能

a. 排序

b. 模糊搜索

  • 实现思路:
    在页面是设置form表单,搜索:以Get形式提交请求到后台,后台获取数据然后进行筛选过滤。
    后端获取到关键字之后,根据定义的列进行查找(多列可以按照或进行查询)。
  • Q

c. 批量操作

  • 增加checkbox列
  • 生成批量操作的"按钮"

d. 组合搜索

  • 什么是组合搜索?
  • 如何实现组合搜索?
    • 实现思路,根据字段找到其相关联的数据:choice、FK、M2M
    • 第一步:配置
    • 第二步:根据配置获取关联数据
    • 第三步:根据配置获取关联数据(含条件)
    • 第四步:在页面上显示组合搜索的按钮
      • 将QuerySet和元组进行封装
    • 第五步:为组合搜索按钮生成URL
      • 生成URL时,不影响其他组的条件
      • 条件筛选
      • 多选

总结:

  • 页面:列表、添加、编辑、删除
  • 模糊搜索、批量操作、组合搜索

第三部分: crm业务开发

1. 项目背景

以教育机构为背景的crm项目,系统主要为 销售部、运营部、教质部 提供平台,对他们的工作进行量化,有利于公司信息化的建设。

  • 销售部

    • 公户,公共客户。
    • 私户,我的客户。 <= 150人 + 跟进记录 + 入班申请(财务审核)
  • 运营部

    • 录入客户信息(公户)
  • 教质部

    • 考勤
    • 学员访谈
    • 积分管理
    • 转班申请

2. 项目开发

2.1 概览

  • 基础业务处理

    • 校区管理
    • 部分管理
    • 用户管理
    • 课程管理
    • 开班管理
  • 客户管理

    • 公户
    • 私户
  • 学员管理

    • 考勤
    • 谈话记录
    • 积分
  • rbac组件

2.2 开发

2.2.1 创建项目
2.2.2 校区管理
2.2.3 部门管理
2.2.4 用户管理
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值