仿照admin的stark自定义组件的功能实现:其中最主要的就是增删改查的实现

1、查:首先页面中显示表头和数据,都是动态的,而不是写死的。

(1) 先看表头和表单数据:这个是查看的视图函数,但是为了使视图函数里边的代码简洁,在默认配置类的外部定义一个展示类,

因为在展示页面上会展示我们数据库中的数据,搜索框,过滤框,等。所以专门定义一个展示类。

# 查看视图函数,将此里边的函数封装成一个函数def listview(self, request):# print(self)  # 当前访问模型表的配置类对象# print(self.model)  # 当前访问模型表# print(self.list_display)if request.method == "POST":# 获取到我们选中的id,即对象pk_list = request.POST.getlist("pk_list")# 看id是否在pk_list中queryset = self.model.objects.filter(pk__in=pk_list)# 或取到这个名字即函数名action = request.POST.get("action")# 因为获取的是字符串,所以要用反射,self表示配置类对象# 判断是否存在if action:action=getattr(self,action)action(request,queryset)data_list = self.model.objects.all()# 在这个页面上增加一个增加数据的按钮,跳转到那个路径add_url = self.get_add_url()# 获取搜索条件对象search_condition = self.get_search_condition(request)# 获取filter的conditionfilter_condition = self.get_filter_condition(request)# 数据过滤展示data_list = data_list.filter(search_condition).filter(filter_condition)# 分页展示showlist = ShowList(self, data_list, request)# filter,调用
        showlist.get_list_filter()return render(request, "list_view.html", locals())

展示类:

class ShowList(object):# 初始化def __init__(self, config_obj, data_list, request):self.config_obj = config_obj  # 当前查看表的配置类对象self.data_list = data_listself.request = request# 分页self.pagination = MyPage(request.GET.get("page", 1),self.data_list.count(),request,per_page_data=3)self.page_queryset = self.data_list[self.pagination.start:self.pagination.end]# actions操作def get_new_actions(self):temp = []temp.extend(self.config_obj.actions)temp.append(self.config_obj.patch_delete)new_actions = []print(self.config_obj.actions)   # [patch_init,patch_delete]这个对象print(temp)for func in temp:new_actions.append({"text":func.desc,"name":func.__name__})# print(new_actions)# [{'text': '价格初始化', 'name': 'patch_init'}, {'text': '批量删除', 'name': 'patch_delete'},return new_actions# 表头函数def get_headers(self):# 构建表头# 想要的形式是这种形式header_list=["书籍名称","价格"]header_list = []for field_or_func in self.config_obj.new_list_display():  # 依然循环["title","price","publish",edit]# 如果是函数的话这样if callable(field_or_func):# 如果是函数val = field_or_func(self.config_obj, is_header=True)else:# # 如果只是单纯的字符串字段# 如果这个字段是__str__if field_or_func == "__str__":val = self.config_obj.model._meta.model_name.upper()print(val)else:# 获取到的是字段里边的verbose_name,如果没这个就是默认的表明field_obj = self.config_obj.model._meta.get_field(field_or_func)val = field_obj.verbose_nameheader_list.append(val)return header_list# 表单数据部分def get_body(self):# 构建数据表单部分new_data_list = []  # 先创建一个外层列表,在这个列表里边放小列表for obj in self.page_queryset:  # 循环 这个对应的列表,Queryset[book1,book2]temp = []  # 小列表for field_or_func in self.config_obj.new_list_display():# 循环的就是你display中的东西,不仅有字段相对应的字符串,还可能有自定义的函数["title","price","publish",edit]# 故要做判断,callable是判断是否是函数,if callable(field_or_func):# 如果是函数,则执行这个函数val = field_or_func(self.config_obj, obj)else:# 如果是字符串,# 如果是多对多字段,先导入一个from django.db.models.fields.related import ManyToManyField# 这个是获取出来字段,try:field_obj = self.config_obj.model._meta.get_field(field_or_func)print(field_obj)# app01.Book.title# app01.Book.price# app01.Book.publish# app01.Book.authorsif isinstance(field_obj, ManyToManyField):# 然后判断哪个字段是多对多字段,isinstance就是判断是否是多对多字段# 如果是就要用.all()全部获取出来,rel_data_list = getattr(obj, field_or_func).all()print(rel_data_list)# 获取出来每本书对应的作者这个对象# <QuerySet [<Author: 沈巍>, <Author: 蓝忘机>]>l = [str(item) for item in rel_data_list]# 经过for循环,并且转成字符串,用|隔开val = "|".join(l)# 如果这个字段在links里边,获取一下路径,生成a标签if field_or_func in self.config_obj.list_display_links:_url = self.config_obj.get_change_url(obj)val = mark_safe("<a href='%s'>%s</a>"%(_url, val))else:# 如果不是多对多字段,就直接获取就行val = getattr(obj, field_or_func)  # 反射# 如果这个字段在links里边,获取一下路径,生成a标签if field_or_func in self.config_obj.list_display_links:_url = self.config_obj.get_change_url(obj)val = mark_safe("<a href='%s'>%s</a>"%(_url, val))except Exception as e:val = getattr(obj, field_or_func)  # 反射# 都添加到小列表中temp.append(val)# 添加到大列表中new_data_list.append(temp)return new_data_list# filter操作,可以写在listview里边,但是为了listview里边代码清晰,所以写在这个类里边def get_list_filter(self):# 这个弄成字典,是为了前端方便获取,而且方便存值list_filter_links = {}# for 循环这个字段列表 ['publish', 'authors']for field in self.config_obj.list_filter:# 因为这个要保存之前的路径parmas = copy.deepcopy(self.request.GET)# 获取当前字段的idcurrent_pk = parmas.get(field, 0)# 获取这个字段的对象field_obj = self.config_obj.model._meta.get_field(field)# 固定语法,得到关联字段的那张表rel_model = field_obj.rel.to# 得到这个表之后,直接获取这个表的所有数据rel_model_queryset = rel_model.objects.all()# < QuerySet[ < Publish: 镇魂出版社 >, < Publish: 忘羡出版社 >, < Publish: 北京出版社 >, < Publish: 晋江出版社 >] ># print(rel_model_queryset)# 得到这个出版社后,在for循环temp = []for obj in rel_model_queryset:# 字典,键是字段,值是id值parmas[field] = obj.pkif obj.pk == int(current_pk):# 如果字典中的id值和当前获取的一致,颜色变色link = "<a class='active' href='?%s'>%s</a>" % (parmas.urlencode(), str(obj))else:# 其他颜色不变化,link = "<a href='?%s'>%s</a>" % (parmas.urlencode(), str(obj))temp.append(link)list_filter_links[field] = tempreturn list_filter_links

如果是自定义列的话,应该将list_display做一下调整

# 定义一个新的列表,既存放字段,有存放edit,delete,checkboxdef new_list_display(self):temp = []# 把我原来的list_display数据添加进去
        temp.extend(self.list_display)# 把checkbox插入在第一位
        temp.insert(0, ModelStark.checkbox)# 继续往后添加edit字符串# 我们因为增加了一个link属性,所以就在这里判断一下,# 如果有links这个属性,我们就不添加增加这个属性了,如果没有的话,我们增加if not self.list_display_links:temp.append(ModelStark.edit)# 继续往后添加删除字符串
        temp.append(ModelStark.delete)return temp

# 默认操作函数def edit(self, obj=None, is_header=False):if is_header:return "操作"return mark_safe("<a href='%s' class='btn btn-warning btn-sm'>编辑</a>" % self.get_change_url(obj))def delete(self, obj=None, is_header=False):if is_header:return "删除"return mark_safe("<a href='%s' class='btn btn-danger btn-sm'>删除</a>" % self.get_delete_url(obj))def checkbox(self, obj=None, is_header=False):if is_header:return "选择"return mark_safe("<input type='checkbox' name='pk_list' value=%s>" % obj.pk)

(2)表单表头部分应该注意的有:

1)在表单数据显示部分有多对多字段的,原生admin是没有做操作的,因为原生的没有规定以什么分割,但是在这里我们进行了操作,是以|分割的,所以可以显示。

2)自定义列的时候,首先判断是普通字段,还是我们自定义的函数,如果是普通字段,因为得到的是字符串,所以用反射就可以实现

转载于:https://www.cnblogs.com/hnlmy/p/9583745.html

仿照admin的stark自定义组件的功能实现相关推荐

  1. 使用Vue自定义组件出现的错误

    前言 ​ 在使用Vue的自定义组件的功能时,出现了一个错误 ​ vue.js:634 [Vue warn]: Unknown custom element: <student> - did ...

  2. Django基于admin的stark组件创建(一)

    首先创建一个名为stark_test的Django项目,创建2个app一个名为app01用来测试stark组件,一个就叫做stark,用来放stark组件 如图: 我们这里使用的是Django自带的数 ...

  3. 如何使用小程序自定义组件功能

    标签: 小程序 component 需求 小程序开发时通过自定义组件将频繁使用的模块抽取出来,简化代码; 实现难点 小程序文档相关的说明太过于详细,以至于不能快速上手使用,因此这里从顽意小程序中拿出一 ...

  4. vue项目通讯录_vue 自定义组件实现通讯录功能

    在线demo:http://tangyupeng.top/dist/index.html#/phone 首页 + 确认 取消 import Vue from 'vue'; import Vuex fr ...

  5. 换肤功能原理及自定义组件化UI样式初步尝试

    只从UI工作开始向前端工作,我一直计划着开发一套属于自己的UI框架,网站通过拖拽点击,或输入布局代码,后台自动生成一套静态页面,从此前端工作仅需要补充各种排版即可,静态页面通过代码生成. 可能我上面的 ...

  6. 小程序css样式+自定义组件+功能

    代码仓库:https://gitee.com/DerekAndroid/miniProgramAgen.git 微信小程序实现图片文字二维码组合拼接成一张图片,下载到手机相册 思路:1下载网络图片,2 ...

  7. 25000字总结Android优秀的第三方框架、各种学习资料汇集 一 系统组件、Design组件、自定义组件等等

    说明 以下内容博主很多也没有用过 分享出来大家一起学习 用到的时候 可以来查看 有问题可以沟通 希望大家不要污染了学习环境 如果觉得有帮助 点个赞 支持一下 系统控件 TextView Github ...

  8. 【说人话】真正意义上讲清楚了如何用$emit()在Vue.js的自定义组件中实现v-model=“”双向绑定

    子组件sg-component.vue代码 <template><div class="sg-component"><button @click=&q ...

  9. Angular系列学习二:基本的组件说明、自定义组件和部分细节说明

    作者:心叶 时间:2018-07-24 16:41 基本说明 组件是Angular中非常重要的一个东西,是拥有模板的指令,是构成Angular应用的基础和核心,被用来包装特定的功能,应用程序的有序运行 ...

最新文章

  1. 分区表--SQLServer创建分区表
  2. 开源中国app说什么 旁边的那个图标是什么drawable
  3. 浅谈ANR及log分析ANR
  4. apache2 的https配置和代理https后端nodejs配置
  5. 软件包管理 2 -----基本知识 rpm yum
  6. Java的IO操作(二) - 带缓冲区的流对象、写入基本数据类型、实现命令行中的copy命令...
  7. 认证服务器的搭建_OAuth2.0分布式系统环境搭建
  8. 【数据库原理及应用】经典题库附答案(14章全)——第十二章:数据库技术新发展
  9. 如何控制油门更准确?
  10. linux shell: 搜索字符串,剔除包含特定字符的行
  11. Fleet究竟是什么?为什么最近这么火~
  12. 编译OpenJDK8:Target CPU mismatch. We are building for x86_64 but CL is for ; expected x64
  13. 自定义scrollview右侧的滑动条
  14. YUI Compressor 进行js/css文件混淆压缩
  15. matlab条件统计个数,matlab计算条件概率
  16. 省市县行政区划代码sql及源地址
  17. LCD LVDS的一些术语定义
  18. Ubuntu18.04 上 安装微信(Deepin-Wechat)
  19. 解决aria2下载磁力链接或bt文件时没有速度或速度为0
  20. 告别Excel!别人家高大上的财务数据分析,这才是老板的最爱

热门文章

  1. 【游戏开发实验】Unity音频效果可视化显示(GetSpectrumData接口)
  2. “5G新体验,合作赢未来”中国移动携合作伙伴打造5G合作生态
  3. 2023 古诗词API接口PHP源码
  4. plot画图保存时不留白色的空边的方法
  5. 进行网络防御的重要性_2019年最强大的10种网络安全软件工具
  6. python练习题__列表
  7. C语言程序设计实践(OJ)-递归函数与宏
  8. 字符串转拼音(包括汉语、英文和数字)
  9. ubuntu13.04电信宽带上网,安装影视播放器
  10. 5min搭建SSM项目