项目经验应对
admin
Django 提供了基于 web 的管理工具。主要功能实现: 增 删 改 查
Django 自动管理工具是 django.contrib 的一部分。你可以在项目的 settings.py 中的 INSTALLED_APPS 看到它:
settings.py INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', ]
django.contrib是一套庞大的功能集,它是Django基本代码的组成部分。
python manage.py createsuperuser
两张默认的表Groups和Users表
admin.site.register([Role, Permission])
class UserAdmin(admin.ModelAdmin): list_display = ('name', 'password',)
list_display_links search_fields 定制HTML模板 fields,增/改页面时,显示字段的字段 readonly_fields,增/改页面时,只读字段
Admin流程:
1. 注册:
Django项目启动时,admin应用__init__.py自动加载函数, 加载所有应用的admin.py文件, 同时生成一个单例对象site=AdminSite()
admin.site.register(UserInfo) 注册表
2. URL配置:
路由的结构:
- admin/应用名/表名
- admin/应用名/表名/add
- admin/应用名/表名/1/change/
- admin/应用名/表名/1/delete/
model类变量下的_meta属性:
print(Book._meta.model_name) # "book"
print(Book._meta.app_label) # "app01"
路由的二级分发
AdminSite(object):类 空字典self._registry = {}, register方法中,self._registry[model] = admin_class(model, self), 键: 是传进来的表对象(不是字符串),
值: 就是 admin_class(model, self)样式类的一个实例化对象(admin_class就是默认的ModelAdmin,如果传第二个参数,就是传进来的类
urls() 是方法, 不是静态属性,@property修饰了
get_url() 动态生成多条url,包括增删改查
----
stark组件
展示页面: 因为是通用的视图,每个表的字段都不一样,构建数据结构[[], [], []...]
## ( 设计表单: 设计数据格式 [[第一条数据], [第二条数据], [第三条数据], ...])
分页: request.GET params._mutable = True params.urlencode() QueryDict类型--request
search功能:
from django.db.models import Q q = Q() # 实例化一个Q对象q q.connector = 'or' # "或" 不写是:"与" q.children.append(("name__contains", "zhou")) # 注意是一个参数 ( append()方法接收一个参数 ) q.children.append(("emai__containsl", "zhou@163.com")) models.Userinfo.objects.filter(q) 效果等同于----: models.Userinfo.objects.filter(Q(name__contains="zhou") | Q(email__contains="zhou@163.com")) --------models.Userinfo.objects.filter(Q()) # filter(Q()) == all()
批量处理:
action_del.desc = '批量删除' # 一切皆对象,给函数(对象)添加一个描述信息的属性
action_func = getattr(self, action_func_name) # 反射,前端传过来的函数名字符串调用对应的方法
前端渲染用 select标签
多对多字段显示:
field_obj=self.model._meta.get_field(field)
if isinstance(field_obj,ManyToManyField): # 多对多字段
queryset_list = getattr(field_obj, 字段).all() # 多对多关联表的对象列表
user_obj.field.all() # 一条具体数据记录.字段.all() === 取出这条记录所有的多对多对象
添加页面: 使用ModelForm, form对象验证用户输入数据格式
popup功能: 点击 “+” 号,加号包含字段关联的表的添加视图的url,window.open打开新窗口,填完数据POST请求, 判断是否有pop_id参数, 判断是不是从点击“+”号过来的
返回一个中间临时页面,做2件事:
1. 找到父窗口页面,调用相应的函数,且把参数传进去,
2. 关闭中间临时窗口页面
父页面的函数调用后,执行里面的代码,在相应的select标签添加option标签,默认选中
isinstance(bound_field.field, ModelChoiceField): # 判断外键,给外键添加链接(到外键字段对应的表的add视图) for boundField in ModelForm(): ModelForm对象 循环得到 boundField对象 <class ‘django.forms.boundfield.BoundField’> boundField.field boundField对象 能找到 form的字段对象 (ModelChoiceField对象, ModelMultipleChoiceField对象, ...) ModelChoiceField.queryset form的字段对象 能拿到 queryset对象 QuerySet.model queryset对象 能找到对应的 表
权限组件
什么权限?
权限: 一个包含正则的URL 例如: /users/delete/(\d+)
(谁权限中有这个URL,谁就能访问)
权限组件:
RBAC: Role-Based Access Control
表结构设计:
from django.db import models class UserInfo(models.Model): name = models.CharField(max_length=32) password = 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) # 权限分组, 把类似相关的url分成一个组 permission_group = models.ForeignKey('PermissionGroup', default='1') # 用户组 订单组 课程组 班级组 一个表就是一个组 codes = models.CharField(max_length=32, default='') # 编号,粒度精确到按钮级别 通过编号判断按钮是否展示 (list list list list add add add add ) parent = models.ForeignKey("self", default=1, null=True, blank=True) # 自关联 根据它的值 None 1 判断一级菜单和二级菜单 def __str__(self): return self.title class PermissionGroup(models.Model): caption = models.CharField(max_length=32) menus = models.ForeignKey("Menu", default=1) def __str__(self): return self.caption class Menu(models.Model): caption = models.CharField(max_length=32) # 菜单名称 def __str__(self): return self.caption
如果所有的二级菜单都是False,那么一级菜单也是False
如果二级菜单存在True,那么一级菜单也是True
浙公网安备 33010602011771号