运维咖啡吧

享受技术带来的乐趣,体验生活给予的感动

sadmin view基类

Sadmin封装了两个基础类,分别是ListCreateViewRetrieveUpdateDestroyView,用来快捷的实现model的增删改查功能

ListCreateView

ListCreateView用来实现model(表)级别的操作,包括列出表里的数据,以及往表里插入数据,分别对应了getpost两个方法,用法如下:

from sadmin.commons.options import ListCreateView, RetrieveUpdateDestroyView

class TaskList(ListCreateView):
    model = Task
    template = 'engine/task.index.html'
    permission = {'get': 'engine.task_select', 'post': 'engine.task_change'}
方法定义

接收两个方法,分别是getpost

get: 获取数据列表

post: 添加单条数据

变量定义

接收几个变量,分别是:modelfilterorderbylist_displaysearch_fieldsproject_filterqueryset_limittemplatepermission

model: 要操作的model

filter: 字符串,在默认QuerySet结尾增加filter,默认QuerySet是self.model.objects.all()self.model.objects.filter(is_deleted=False),根据model中是否有is_deleted字段来确定,当filter有值时,则会在QuerySet后跟上filter的值,例如filter='.filter(state=8)',则最终的QuerySet语句就是self.model.objects.all().filter(state=8)

orderby: 列表,根据orderby定义的排序列表,生成排序语句添加到QuerySet结尾,例如orderby=['-id'],则最终的QuerySet语句是self.model.objects.all().order_by("-id"),orderby位于QuerySet的末尾

list_display: 列表,定义要显示的字段,默认显示所有字段,如果list_display存在时则显示list_display定义的字段,主要在最终返回时过滤,通过model_to_dictfields实现model_to_dict(_data, fields=self.list_display, exclude=self.many_to_many_fields),所以当list_display与model定义的to_dict冲突时,以to_dict为准

search_fields: 列表,定义模糊搜索时搜索的字段,默认会搜索所有['GenericIPAddressField', 'CharField', 'TextField', 'EmailField', 'JSONField']类型的字段,若search_fields存在,则会在search_fields定义的字段中搜索

project_filter: 布尔值,定义是否根据project过滤,默认为True,当表字段中存在project字段时,仅过滤用户当前project的数据,用户当前project从两个地方获取,1.用户请求里的project参数,2.浏览器Cookies里的project参数

queryset_limit: 布尔值,定义是否限制数据展示条数,默认为True,也就是默认限制数据展示条数,默认最多展示100条数据,当需要一次性展示所有数据时,可以设置为False,注意:当表数据较多时设置为False会有性能问题

template: 字符串,定义list模板,如果模板为空则返回JsonResponse,如果模板不为空则返回render并附带lPage变量,可直接在模板中循环使用

permission: 字典,定义权限,字典类型,分别定义getpost的权限,permission的value除了权限定义字符串外,还有几个保留字段,分别是superuserlogin_useranonymous_user,详细用法如下

字段过滤

当请求包含字段参数时,则会根据字段参数过滤数据,例如请求:?project=ops-coffee&format=json,则最终的QuerySet是self.model.objects.all().filter(project="ops-coffee")

排序

当请求包含sort参数时,可以根据sort参数的值进行排序,例如请求:?sort=sortnum,则最终的QuerySet是self.model.objects.all().orderby('sortnum'),请求的参数sort会和view中定义的变量orderby整合,具体的是sort+orderby取交集,sort在前,orderby在后,例如前端请求是?sort=sortnum,而view配置了orderby参数是orderby=[-id],则最终的QuerySet会是self.model.objects.all().orderby('sortnum','-id'),sort一次可以传多个,多个用逗号隔开,例如?sort=sortnum,name,age

切片

当强求包含start和length参数时,可以根据start和length参数的值进行数据切片,例如请求:?start=1&length=10,则最终的QuerySet是self.model.objects.all()[1:11]

datatables兼容

当前端是datatables异步发来的请求时则会返回datatables所需要的最终格式,包含drawrecordsTotalrecordsFiltereddata

{
    "draw": int(request.GET.get('draw')),
    "recordsTotal": _recordsTotalCount,
    "recordsFiltered": eval(_queryset + '.count()'),
    "data": _table_data
}
自定义函数

当查询条件比较复杂,通过filter无法满足需求时,可以使用get_queryset自定义方法来定义更为复杂的查询条件。get_queryset返回一个queryset的字符串,这个字符串会跟后续的查询条件等拼接

class TasklogList(ListCreateView):
    model = TaskLog
    orderby = ['-id']
    template = 'engine/tasklog.index.html'
    permission = {'get': 'engine.tasklog_select'}

    @staticmethod
    def get_queryset(request):
        tasks = [i.id for i in get_tasks_for_user(request)]
        return 'self.model.objects.filter(task_id__in={})'.format(tasks)

当权限定义比较复杂,通过permission无法满足需求时,可以使用valid_permission自定义方法来定义更为复杂的权限验证。valid_permission返回一个布尔值,根据这个布尔值来确定是否有权限,如果为True则有权限,为False则无权限

class TaskDetail(RetrieveUpdateDestroyView):
    model = Task

    def valid_permission(self, request, pk):
        return True if self.model.objects.get(id=pk) in get_tasks_for_user(request) else False

RetrieveUpdateDestroyView

RetrieveUpdateDestroyView用来实现object(行)级别的操作,包括获取某条数据的详情、修改某条数据或时删除某条数据,分别对应了getputdelete三个方法,用法如下:

class TaskDetail(RetrieveUpdateDestroyView):
    model = Task
    template = 'engine/task.detail.html'
    permission = {'get': 'engine.task_select', 'put': 'engine.task_change', 'delete': 'engine.task_change'}
方法定义

接收三个方法,分别是getputdelete

get: 获取单条数据

put: 更新单条数据

delete: 删除单条数据,当model中存在is_deleted字段时,则会进行逻辑删除,也就是仅修改is_deleted字段为True,并不会实际从数据库中删除数据

变量定义

接收几个变量,分别是:modeltemplatepermissionproject_filter

model: 要操作的model

template: 字符串,定义detail模板,如果模板为空则返回JsonResponse,如果模板不为空则返回render并附带data变量,可直接在模板中使用,通过{{ data.field_name }}来获取数据

permission: 字典,定义权限,定义getputdelete的权限,permission的value除了List中定义的superuserlogin_useranonymous_user三个保留字段外,还多了个保留字段owner,当权限值为owner时仅数据创建者有操作权限,前提是model中要有create_user字段,create_user字段记录的就是数据创建者

project_filter: 布尔值,定义是否根据project过滤,默认为True,当表字段中存在project字段时,则在操作数据前会先判断用户是否有当前项目的权限,用户当前project仅从要操作的数据字段里获取