stark组件

1. stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件
2. setting文件下INSTALLED_APPS 路径要配置好(app的注册)
3. 写好sites.py中的site类,实例化出一个类对象,其他文件都直接引用这个类对象(单例模式),
4. 模型类和数据库也要确定好
from django.urls import path,re_path
from django.shortcuts import HttpResponse,render,redirect from django.utils.safestring import mark_safe
from django.core.exceptions import FieldDoesNotExist
from django.urls import reverse
from django.db.models import Q
class ShowList(object):
def __init__(self,request,config_obj,queryset): #展示页面的自定制变量
self.config_obj=config_obj
self.queryset=queryset
self.request=request
self.pager_queryset=self.get_pager_queryset() #分页 def get_pager_queryset(self): #分页功能 from stark.utils.page import Pagination #一般是在stark组件下新建一个文件夹写好功能后直接倒过来
current_page = self.request.GET.get("page", 1)
self.pagination = Pagination(self.request, current_page, self.queryset, per_page_num=self.config_obj.per_page_num or 5)
queryset = self.queryset[self.pagination.start:self.pagination.end] return queryset def get_header(self):
'''
获取表头
:return:
'''
# 构建表头 header_list = []
for field_or_func in self.config_obj.get_new_list_display():
if callable(field_or_func):
val = field_or_func(self.config_obj, header=True)
header_list.append(val)
# header_list.append(field_or_func.__name__)
else:
if field_or_func == "__str__":
val = self.config_obj.model._meta.model_name.upper()
print(val)
else:
field_obj = self.config_obj.model._meta.get_field(field_or_func)
val = field_obj.verbose_name
header_list.append(val) return header_list def get_body(self):
'''
获取标体
:return:
'''
# 构建展示数据
new_data = []
for obj in self.pager_queryset:
temp = [] for field_or_func in self.config_obj.get_new_list_display(): # ["title","price","state","publish",show_authors]
if callable(field_or_func):
# field:方法
val = field_or_func(self.config_obj, obj)
else:
try:
# field:字符串
from django.db.models.fields.related import ManyToManyField
field_obj = self.config_obj.model._meta.get_field(field_or_func)
# 判断是否多对多字段
if type(field_obj) == ManyToManyField:
raise Exception("list_display不能是多对多字段!")
# 判断字段是否 拥有choices属性
if field_obj.choices:
val = getattr(obj, "get_%s_display" % field_or_func)()
else:
val = getattr(obj, field_or_func)
if field_or_func in self.config_obj.list_display_links:
val = mark_safe("<a href='%s'>%s</a>" % (self.config_obj.get_change_url(obj), val)) except FieldDoesNotExist as e:
# val=obj
val = getattr(obj, field_or_func)() temp.append(val)
new_data.append(temp) print("new_data", new_data) # [['python', Decimal('123.00')], ['java', Decimal('234.00')]] '''
目标数据结构
new_data=[
["python",123],
["java",234]
]
''' return new_data class ModelStark(object):
'''
默认配置类
'''
list_display=("__str__",)
list_display_links = []
model_form_class=None
per_page_num=None
search_fields=[]
search_val=None
list_filter=[]
list_title=None def __init__(self,model):
self.model=model
self.model_name = self.model._meta.model_name
self.app_label = self.model._meta.app_label # 反向解析当前访问表的增删改查URL
def get_list_url(self):
# 反向解析当前表的删除的URL
list_url = reverse("%s_%s_list" % (self.app_label, self.model_name))
return list_url def get_add_url(self):
# 反向解析当前表的删除的URL
add_url = reverse("%s_%s_add" % (self.app_label, self.model_name))
return add_url def get_delete_url(self,obj):
# 反向解析当前表的删除的URL
delete_url = reverse("%s_%s_delete" % (self.app_label, self.model_name), args=(obj.pk,))
return delete_url def get_change_url(self, obj):
# 反向解析当前表的删除的URL
change_url = reverse("%s_%s_change" % (self.app_label, self.model_name), args=(obj.pk,))
return change_url # 三个默认列
def show_checkbox(self, obj=None, header=False):
if header:
return mark_safe("<input type='checkbox'>")
return mark_safe("<input name='_selected_action' value=%s type='checkbox'>"%obj.pk) def show_delbtn(self, obj=None, header=False):
if header:
return "删除" return mark_safe("<a href='%s'>删除</a>"%self.get_delete_url(obj)) def show_editbtn(self, obj=None, header=False):
if header:
return "编辑"
return mark_safe("<a href='%s'>编辑</a>" %self.get_change_url(obj)) # 构建新的list_display def get_new_list_display(self):
temp=[]
temp.extend(self.list_display)
temp.append(ModelStark.show_editbtn)
temp.append(ModelStark.show_delbtn)
temp.insert(0,ModelStark.show_checkbox) return temp def get_search_condition(self,request):
val = request.GET.get("q") q = Q()
if val:
self.search_val = val
q.connector = "or"
for field in self.search_fields: # ["title","price"]
print(field)
# queryset=queryset.filter(Q(title__contains=val)|Q(price__contains=val))
q.children.append((field + "__contains", val))
else:
self.search_val=None return q # action参数
def patch_delete(self,request,queryset): # [1,3]
queryset.delete() patch_delete.desc="批量删除" actions=[]
def get_new_actions(self):
temp=[]
temp.extend(self.actions)
temp.append(self.patch_delete)
return temp def get_action_dict(self):
actions_list=[]
for func in self.get_new_actions():
actions_list.append({
"name":func.__name__,
"desc":func.desc,
}) return actions_list # [{"name":"patch_delete","desc":"批量删除"}] def get_list_filter_links(self): list_filter_links={} print(self.list_filter) # ["publish","authors","state"] for filter_field in self.list_filter:
import copy
params = copy.deepcopy(self.request.GET) # {"publish":1,"authors":1}
current_field_val=params.get(filter_field) filter_field_obj=self.model._meta.get_field(filter_field)
print(">>>",type(filter_field_obj))
from django.db.models.fields.related import ForeignKey,ManyToManyField
# 针对一对多或者多对多过滤字段
if isinstance(filter_field_obj,ForeignKey) or isinstance(filter_field_obj,ManyToManyField):
# print("____>",filter_field_obj.remote_field.model) # <class 'app01.models.Publish'>
# data=filter_field_obj.remote_field.model.objects.all()
# print(data)
rel_model = filter_field_obj.remote_field.model
_limit_choices_to = filter_field_obj.remote_field.limit_choices_to
data = rel_model.objects.filter(**_limit_choices_to)
elif filter_field_obj.choices:
# 针对choice字段类型
data=filter_field_obj.choices # [(1,"已出版"),(2,"未出版社")]
else:
raise Exception("过滤字段不能太普通!") # 为每一个数据构建成一个a标签
temp = []
# params2=copy.deepcopy(params)
if params.get(filter_field):
del params[filter_field] all = "<a class='btn btn-default btn-sm' href='?%s'>全部</a>"%params.urlencode()
temp.append(all) for item in data:
if type(item)==tuple:
# 元组类型
pk,text = item
else:
# model对象类型
pk,text = item.pk,str(item) params[filter_field]=pk # ***********
_url="?%s"%(params.urlencode()) # *********** if current_field_val==str(pk):
link="<a class='active btn btn-default btn-sm' href='%s'>%s</a>"%(_url,text)
else:
link = "<a class='btn btn-default btn-sm' href='%s'>%s</a>" % (_url, text) temp.append(link) list_filter_links[filter_field]=temp return list_filter_links def get_list_filter_condition(self): q=Q()
for filter_field,val in self.request.GET.items():
if filter_field in ["page","q"]:continue
q.children.append((filter_field,val)) return q # 视图函数
def list_view(self,request,querySet=None,flag=False):
'''
self: 当前访问模型表对应的配置类对象
self.model: 当前访问模型表
:param request:
:return:
'''
self.request=request if request.method=="POST":
# action操作
action_func_str=request.POST.get("action")
if action_func_str:
action_func=getattr(self,action_func_str)
_selected_action=request.POST.getlist("_selected_action") # [1,3]
queryset=self.model.objects.filter(pk__in=_selected_action)
action_func(request,queryset) if not flag:
# print("self.model.__class__",self.__class__.__dict__)
self.list_filter=self.__class__.__dict__.get("list_filter",[])
self.actions=self.__class__.__dict__.get("actions",[])
self.list_title=self.__class__.__dict__.get("list_title",[])
if flag:
queryset=querySet
else:
queryset=self.model.objects.all() # search过滤
search_condition=self.get_search_condition(request)
# list_filter多级过滤
list_filter_condition=self.get_list_filter_condition() queryset=queryset.filter(search_condition).filter(list_filter_condition) show_list=ShowList(request,self,queryset) # 相关变量
table_name=self.model._meta.verbose_name
add_url=self.get_add_url() # # 获取登录人权限
# print("Per:",request.session.get("permission_list"))
# permission_list=request.session.get("permission_list")
# menu_permissions=[]
# for permission in permission_list:
# if permission.get("type")=="button":continue
# menu_permissions.append(permission) import datetime
now=datetime.datetime.now() title=self.list_title or "查看数据"
return render(request,'stark/list_view.html',locals()) def get_model_form(self):
from django.forms import ModelForm
class BaseModelForm(ModelForm):
class Meta:
model = self.model
fields = "__all__" return self.model_form_class or BaseModelForm def add_view(self,request):
BaseModelForm=self.get_model_form() if request.method=="GET":
form_obj=BaseModelForm()
print(form_obj)
return render(request,"stark/add_view.html",locals())
else:
form_obj = BaseModelForm(request.POST)
if form_obj.is_valid():
form_obj.save()
return redirect(self.get_list_url())
else:
return render(request, "stark/add_view.html", locals()) def change_view(self,request,id):
BaseModelForm=self.get_model_form()
edit_obj=self.model.objects.filter(pk=id).first()
if request.method=="GET":
form_obj=BaseModelForm(instance=edit_obj)
return render(request,"stark/change_view.html",locals())
else:
form_obj = BaseModelForm(request.POST,instance=edit_obj)
if form_obj.is_valid():
form_obj.save()
return redirect(self.get_list_url())
else:
return render(request, "stark/change_view.html", locals()) def delete_view(self,request, id): if request.method=="POST":
self.model.objects.filter(pk=id).delete()
return redirect(self.get_list_url()) list_url=self.get_list_url()
return render(request,"stark/delete_view.html",locals()) def get_extra_url(self): return [] @property
def get_urls(self): temp = [
path("", self.list_view,name="%s_%s_list"%(self.app_label,self.model_name)),
path("add/", self.add_view,name="%s_%s_add"%(self.app_label,self.model_name)),
re_path("(\d+)/change/", self.change_view,name="%s_%s_change"%(self.app_label,self.model_name)),
re_path("(\d+)/delete/", self.delete_view,name="%s_%s_delete"%(self.app_label,self.model_name)), ] temp.extend(self.get_extra_url())
return (temp, None, None) class StarkSite:
'''
stark全局类
'''
def __init__(self):
self._registry = {} def register(self, model, admin_class=None, **options):
admin_class = admin_class or ModelStark
self._registry[model] = admin_class(model) def get_urls(self):
# 动态为注册的模型类创建增删改查URL
temp = []
# {Book:ModelAdmin(Book),Publish:ModelAdmin(Publish)}
for model, config_obj in self._registry.items():
print("---->", model, config_obj)
model_name = model._meta.model_name
app_label = model._meta.app_label
temp.append(
path("%s/%s/" % (app_label,model_name),config_obj.get_urls)
) '''
path("stark/app01/book",BookConfig(Book).list_view)
path("stark/app01/book/add",BookConfig(Book).add_view)
path("stark/app01/publish",ModelAdmin(Publish).list_view)
path("stark/app01/publish/add",ModelAdmin(Publish).add_view) ''' return temp @property
def urls(self):
return self.get_urls(),None,None site = StarkSite()

CRM-stark组件的更多相关文章

  1. crm——stark组件核心原理

    关于stark组件的简要介绍: 启动后.路由加载前定制一段代码.         a. 创建一个 stark  app 组件                  b. 编写ready方法 from dj ...

  2. CRM项目之stark组件(2)

    那么从今天开始呢,我们就要开始设计属于我们自己的admin组件,起个名字就叫stark吧(当然你愿意叫什么都可以). stark组件之四步走 仿照admin组件实现流程,stark组件要实现四件事情: ...

  3. CRM系统之stark组件流程分析

    CRM系统主要通过自定义stark组件来实现的(参照admin系统自定义): STARK组件: 1 admin组件 1 如何使用admin 2 admin源码 3 创建自己的admin组件:stark ...

  4. day 70 crm(7):stark组件调用,以及权限分配

    前情提要: 复习:  1: orm !!!!! 2: session 3: django 4:  前端在复习 5:  复习中间件 学习的stark 的组件调用,以及权限的应用 一:权限的概念,  1: ...

  5. crm项目-stark组件分析

    ###############    stark组件     ################ """ 这个stark组件是非常神奇的 1,独立的一个组件 2,没有mod ...

  6. crm项目-stark组件

    ###############  admin基本认识和常用的定制功能    ############### stark组件 对admin的基本认识 1,就是一个app,嵌入到了django里面,你可以 ...

  7. CRM项目之stark组件

    . stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件 . setting文件下INSTALLED_APPS 路径要配置好(app的注册) . 写好si ...

  8. day67 crm(4) stark组件的增删改 以及 model_from使用和from组件回顾

        前情提要:Django  stark 组件开发的 增删改,  model_form组件的使用 form组件的回顾 一:list_display_link  创建 功能描述:   使包含的字段能 ...

  9. crm 使用stark组件

    # Create your models here. from django.db import models class Department(models.Model): "" ...

  10. crm项目之stark组件前戏(二)

    stark组件的设计主要来源于django中admin的功能,在django admin中只需要将模型表进行注册,就可以在页面对该表进行curd的动作,那么django admin是如何做的呢? 在d ...

随机推荐

  1. Get teststep of specific type

    SoapUI Groovy : Check if test step is of specific type, such as : Wsdl, Rest, Jdbc, HTTP, Groovy etc ...

  2. [面经]杭州某初创公司FPGA工程师实习

    面试时间:2017年8月17日 面试时长:约1小时 面试形式:面对面 面试公司:杭州某初创公司,致力于开发VR相关产品 面试职位:FPGA工程师(实习) 面试官:公司现任FPGA开发工程师,双控硕士毕 ...

  3. 20175224 2018-2019-2 《Java程序设计》第三周学习总结

    教材学习内容总结 编程语言发展的几个阶段 面向机器语言 面向过程语言 面向对象语言 封装性 继承性 多态性 类 类是Java程序的基本要素,一个Java应用程序就是由若干个类所构成的. 类是Java语 ...

  4. Java垃圾回收机制和注解

  5. 20165214 2018-2019-2 《网络对抗技术》Exp3 免杀原理与实践 Week5

    <网络对抗技术>Exp3 免杀原理与实践 Week5 一.实验内容 1.正确使用msf编码器,msfvenom生成如jar之类的其他文件,veil-evasion,加壳工具,使用shell ...

  6. MySQL5.7关于密码二三事

    MySQL5.7关于密码二三事 第一个:update user set password=password('root') where user='root' and host='localhost' ...

  7. h5页面使用sessionStorage滚动到上次浏览器位置《原创》

    前言: 因最近移动端开发过程中遇到一个运营提出的所谓技术难点需求,对于原生APP来说轻而易举,毕竟自己的APP用户操作指哪打哪,但是H5该怎么做?H5就实现不了么?对于一个爱研究攻克这些前端棘手问题的 ...

  8. holer实现外网访问本地网站

    外网访问本地网站 本地搭建了网站,只能在局域网内访问,怎样从公网也能访问内网网站? 本文将介绍使用holer实现的具体步骤. 1. 准备工作 1.1 安装并启动网站服务端 默认搭建的网站服务端端口是8 ...

  9. Red Hat Enterprise 7.5 安装后无法进入图形界面 This system is not registered with an entitlement server. You can use subscription-manager to register.

    This system is not registered with an entitlement server. You can use subscription-manager to regist ...

  10. Breadth-first search

    given a graph G  and a distinguished source vertex s, breadth-firstsearch systematically explores th ...