项目经验应对

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

 

posted @ 2018-06-07 00:54  静静别跑  阅读(104)  评论(0)    收藏  举报