CRM-stark组件
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组件的更多相关文章
- crm——stark组件核心原理
关于stark组件的简要介绍: 启动后.路由加载前定制一段代码. a. 创建一个 stark app 组件 b. 编写ready方法 from dj ...
- CRM项目之stark组件(2)
那么从今天开始呢,我们就要开始设计属于我们自己的admin组件,起个名字就叫stark吧(当然你愿意叫什么都可以). stark组件之四步走 仿照admin组件实现流程,stark组件要实现四件事情: ...
- CRM系统之stark组件流程分析
CRM系统主要通过自定义stark组件来实现的(参照admin系统自定义): STARK组件: 1 admin组件 1 如何使用admin 2 admin源码 3 创建自己的admin组件:stark ...
- day 70 crm(7):stark组件调用,以及权限分配
前情提要: 复习: 1: orm !!!!! 2: session 3: django 4: 前端在复习 5: 复习中间件 学习的stark 的组件调用,以及权限的应用 一:权限的概念, 1: ...
- crm项目-stark组件分析
############### stark组件 ################ """ 这个stark组件是非常神奇的 1,独立的一个组件 2,没有mod ...
- crm项目-stark组件
############### admin基本认识和常用的定制功能 ############### stark组件 对admin的基本认识 1,就是一个app,嵌入到了django里面,你可以 ...
- CRM项目之stark组件
. stark也是一个app(用startapp stark创建),目标时把这个做成一个可以拔插的组件 . setting文件下INSTALLED_APPS 路径要配置好(app的注册) . 写好si ...
- day67 crm(4) stark组件的增删改 以及 model_from使用和from组件回顾
前情提要:Django stark 组件开发的 增删改, model_form组件的使用 form组件的回顾 一:list_display_link 创建 功能描述: 使包含的字段能 ...
- crm 使用stark组件
# Create your models here. from django.db import models class Department(models.Model): "" ...
- crm项目之stark组件前戏(二)
stark组件的设计主要来源于django中admin的功能,在django admin中只需要将模型表进行注册,就可以在页面对该表进行curd的动作,那么django admin是如何做的呢? 在d ...
随机推荐
- HIVE中IN的坑
问题:为什么HIVE中用了 NOT IN,结果集没了? 注:这个是原创,转载请注明,谢谢!直接进实验室>> > select * from a;OK1 a12 a23 a3Time ...
- Delphi 对ini文件的操作
界面如图: 代码如下: unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Vari ...
- Mantis:Mantis rest api url 404 Not Found.解决过程纪录
测试Mantis rest api时碰到的问题:404 Not Found. 根据文件,Mantis rest api的预设url是{{url}}/api/rest/{{controller}}. 其 ...
- Java IO总结
- 大数据处理N!(21<N<2000)
输入: 每行输入1个正整数n,(0<n<1000 000) 输出: 对于每个n,输出n!的(十进制)位数 digit, 和最高位数firstNum.(n!约等于 firstNum * 10 ...
- 微信小程序中的小小的遮罩层
<view class='pop_wx_er'> <view>ddddddddddddd</view> <view>ddddddddddddd</ ...
- 命令行窗口中使用pip安装第三方库成功之后,在pycharm中仍不能使用
在学习廖老师的Python教程的时候,遇到命令行窗口中使用pip安装第三方库成功之后,在pycharm中仍不能使用的情况, 这种情况可能是由于在本地安装了多个Python版本的缘故(只是可能的情况之一 ...
- LoadRunner学习笔记(1)--异常处理方法
1.查看端口号占用情况 cmd -> netstat -ano 找到进程关闭后在重启网站 2.LR录制脚本时为何不弹出IE浏览器 启动浏览器,打开Internet选项对话框,切换到高级标签 ...
- CAShapeLayer绘图
之前讲过使用UIBezierPath在UIView的drawRect中绘图, 今天我们讲下另外一种方式: CAShaperLayer 先说说使用CAShapeLayer的优点: GPU执行, GPU执 ...
- 调试利器GDB(下)
本节我们研究gdb更深层的用法: 数据断点: 可以根据变量的值来监视变量. 数据断点本质是硬件断点,数量有限. watch var_name告诉gdb我们关注var_name这个变量,如果它的值被改变 ...