类Xadmin插件--海豚插件
生活随笔
收集整理的這篇文章主要介紹了
类Xadmin插件--海豚插件
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
一款類似于xadmin的仿制Django內(nèi)部admin管理的插件。用于系統(tǒng)開發(fā)。起個(gè)好聽的名字。海豚插件。
?
?
from django.contrib import admin from Dolphin.service.Dolphin import site,ModelDolphin from django.shortcuts import HttpResponse,render,redirect,reverse from django.utils.safestring import mark_safe from ocas.models import * from django.forms import ModelForm # Register your models here.class CompanyConfig(ModelDolphin):# def xxx(self,obj=None,header=False):# if header:# return "顯示標(biāo)題(可修改)"# return 123 list_display=('id','full_name','short_name','registered_capital','quality_management_system_certificate',"occupational_health_and_safety_system_certificate",'environmental_management_system_certificate','staff_headcount','staff_productor_count','staff_main_network_engineer_count','b_city','qualifications')list_display_links = ("full_name",)search_fields = ('full_name',)list_per_page=5# def patch_init(self,request,queryset):# print(queryset)# patch_init.short_description = "批量初始化"# actions = (patch_init,) list_filter = ('b_city','qualifications','using_software',)# class StaffModelForm(ModelForm):class Meta:model=Stafffields="__all__"exclude=('is_delete',)class StaffConfig(ModelDolphin):list_display = ('id','sjdw','user','gender','native_place',)modelform_class = StaffModelFormsearch_fields = ('user',)list_filter = ('sjdw',)class SoftwareConfig(ModelDolphin):# list_display = ('id',)list_per_page = 5site.register(Company,CompanyConfig) site.register(Qualification) site.register(Software,SoftwareConfig) site.register(Vendor) site.register(City) site.register(Staff,StaffConfig) site.register(UserInfo,) # print(site._registry)?
?
?
#!/usr/bin/env python3 #-*- coding:utf-8 -*- ''' Administrator 2019/2/20 ''' from django.urls import include, path, re_path from django.conf.urls import url from django.shortcuts import HttpResponse,render,redirect,reverse from django.utils.safestring import mark_safe from collections import deque from django.forms import ModelForm from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger import copy from django.db.models import Q from django.db.models.fields.related import ManyToManyField,ForeignKey from django.forms.models import ModelMultipleChoiceField,ModelChoiceField from django.forms.fields import BooleanField # from Dolphin.service.dolform import ModelFormDemo class ShowList(object):def __init__(self,config,data_list,request):self.config=configself.data_list=data_listself.request=requestself.page_data=self.get_query_sets()#actionself.actions=self.config.new_actionsdef get_action_list(self):temp=[]# print(self.actions)for func_obj in self.actions:temp.append({"name":func_obj.__name__,# "desc":func_obj.short_description# "desc":getattr(func_obj,"short_description",func_obj.__name__)"desc":func_obj.short_description if hasattr(func_obj, "short_description") else func_obj.__name__})return tempdef get_header(self):# 構(gòu)建表頭數(shù)據(jù)header_list = []for filed in self.config.new_list_play():if callable(filed):# header_list.append(filed.__name__.upper())header_list.append(filed(self.config, header=True))elif filed == "__str__":header_list.append(self.config.model._meta.model_name.upper())else:header_list.append(self.config.model._meta.get_field(filed).verbose_name)# header_list.append(filed[:10].upperreturn header_listdef get_body(self):new_data_list = []for obj in self.page_data:temp = []for field in self.config.new_list_play():if callable(field):val = field(self.config, obj)else:try:field_obj=self.config.model._meta.get_field(field)if isinstance(field_obj,ManyToManyField):ret = getattr(obj, field).all()t = []for m2m_obj in ret:t.append('''<span class='label label-primary'>{0}</span>'''.format(m2m_obj))val=mark_safe('<br>'.join(t))else:val = getattr(obj, field)if field in self.config.list_display_links:_url = self.config.reverse_url("change", obj)val = mark_safe("<a href={0}>{1}</a>".format(_url, val))except Exception as e:val = getattr(obj, field)# if field in self.config.list_display_links:# _url = self.config.reverse_url("change", obj)# val = mark_safe("<a href={0}>{1}</a>".format(_url, val)) temp.append(val)new_data_list.append(temp)return new_data_listdef get_query_sets(self):paginator = Paginator(self.data_list, self.config.list_per_page)page = self.request.GET.get('page')try:query_sets = paginator.page(page)except PageNotAnInteger:query_sets = paginator.page(1)except EmptyPage:query_sets = paginator.page(paginator.num_pages) # Paginator.num_pages:總共分頁數(shù)return query_setsdef new_pagination(self):params = copy.deepcopy(self.request.GET) # {"page":"12","title_startwith":"py","id__gt":"5"}url_prefix = self.request.path#當(dāng)前路徑page_html=""added_dot_ele = Falsefor page_num in self.page_data.paginator.page_range:params["page"] = page_numif page_num<3 or page_num>self.page_data.paginator.num_pages-2 \or abs(self.page_data.number-page_num)<=2:#代表前面兩頁和后面兩頁ele_class=""if self.page_data.number==page_num:added_dot_ele=Falseele_class="active"page_html+='''<li class="{0}"><a href="{1}?{2}">{3}</a></li>'''.format(ele_class,url_prefix,params.urlencode(),page_num)else:if not added_dot_ele:page_html += '<li><a>...</a></li>'added_dot_ele = Trueif self.page_data.has_previous():params["page"] = self.page_data.previous_page_number()page_html='''<li><a href="{0}?{1}">?</a></li>'''.format(url_prefix,params.urlencode())+page_htmlelse:page_html='''<li class="disabled" ><a href="javascript:void(0);">?</a></li>'''+page_htmlif self.page_data.has_next():params["page"] =self.page_data.next_page_number()page_html+='''<li><a href="{0}?{1}">?</a></li>'''.format(url_prefix,params.urlencode())else:page_html+='''<li class="disabled" ><a href="javascript:void(0);">?</a></li>'''return page_htmldef get_filter_linktags(self):link_list={}url_prefix = self.request.path # 當(dāng)前路徑for filter_field in self.config.list_filter:params = copy.deepcopy(self.request.GET)cid=self.request.GET.get(filter_field,0)filter_field_obj=self.config.model._meta.get_field(filter_field)filter_field_verbose_name="以 {0}".format(filter_field_obj.verbose_name)if isinstance(filter_field_obj,ForeignKey) or isinstance(filter_field_obj,ManyToManyField):# data_list=filter_field_obj.rel.to.objects.all() #django 1.0的用法data_list=filter_field_obj.related_model.objects.all()#django 2.0 的用法else:data_list=self.config.model.objects.values("pk",filter_field)temp=[]#處理 全部標(biāo)簽if params.get(filter_field):del params[filter_field]active = ""else:active = "active"temp.append('''<li class={0}><a href='{1}?{2}'>全部</a></li>'''.format(active,url_prefix,params.urlencode(),))for obj in data_list:if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField):pk=obj.pktext=str(obj)params[filter_field] = pkelse:pk=obj.get("pk")text=obj.get(filter_field)params[filter_field] = textif cid==str(pk) or cid==text:active="active"else:active=""# params[filter_field]=pka_ele = '''<li class={0}><a href='{1}?{2}'>{3}</a></li>'''.format(active,url_prefix,params.urlencode(),text)temp.append(a_ele)# link_list[filter_field_verbose_name]=tempreturn link_listclass ModelDolphin(object):list_display = ('__str__',)list_display_links = ()list_per_page=10#默認(rèn)每頁展示10行數(shù)據(jù)search_fields=()#關(guān)鍵詞搜索actions=()#自定義字段list_filter=()#分組查詢#用戶可以自定義ModelFormmodelform_class=Nonedef __init__(self,model,site):self.model=modelself.site=sitedef reverse_url(self,string,obj=None):app_label = self.model._meta.app_labelmodel_name = self.model._meta.model_nameif string in ["change","delete",]:_url = reverse("{app_label}_{model_name}_{action}".format(app_label=app_label, model_name=model_name,action=string),args=(obj.pk,))return _urlelif string in ["add","list"]:_url = reverse("{app_label}_{model_name}_{action}".format(app_label=app_label, model_name=model_name,action=string),)return _urlelse:raise AttributeError("參數(shù)有誤,沒有這個(gè)屬性.只能使用 change/delete/add/list")def edit(self,obj=None,header=False):if header:return "編輯"app_label = self.model._meta.app_labelmodel_name = self.model._meta.model_name# _url =reverse( "{app_label}_{model_name}_change".format(app_label=app_label, model_name=model_name),args=(obj.pk,))_url=self.reverse_url("change",obj)# return mark_safe("<a href='{0}/change'>編輯</a>".format(obj.pk))return mark_safe("<a href='{_url}'>編輯</a>".format(_url=_url,pk=obj.pk))def deletes(self,obj=None,header=False):if header:return "刪除"# app_label = self.model._meta.app_label# model_name = self.model._meta.model_name# _url = reverse("{app_label}_{model_name}_delete".format(app_label=app_label, model_name=model_name),# args=(obj.pk,))_url=self.reverse_url("delete",obj)return mark_safe('''<a href='{_url}'>刪除</a>'''.format(_url=_url))def checkbox(self,obj=None,header=False):if header:return mark_safe("<input id='choice' type='checkbox'/>")return mark_safe("<input class='choice_item' type='checkbox' name='selected_pk' value='{val}'/>".format(val=obj.pk))def new_list_play(self):temp=[]temp.append(ModelDolphin.checkbox)temp.extend(self.list_display)if not self.list_display_links:temp.append(ModelDolphin.edit)temp.append(ModelDolphin.deletes)return tempdef display_all_related_objs(self,objs):#objs=[objs,]ul_ele="<ul>"for obj in objs:li_ele='''<li>{0}:{1}</li>'''.format(obj._meta.verbose_name,obj.__str__().strip("<>"))ul_ele+=li_elefor m2m_field in obj._meta.local_many_to_many:sub_ul_ele="<ul>"m2m_field_obj=getattr(obj,m2m_field.name)for o in m2m_field_obj.select_related():li_ele = '''<li>{0}:{1}</li>'''.format(m2m_field.verbose_name, o.__str__().strip("<>"))sub_ul_ele+=li_elesub_ul_ele+="</ul>"ul_ele+=sub_ul_elefor related_obj in obj._meta.related_objects:if 'ManyToManyRel' in related_obj.__repr__():if hasattr(obj, related_obj.get_accessor_name()): # hassattr(customer,'enrollment_set')accessor_obj = getattr(obj, related_obj.get_accessor_name())# print("-------ManyToManyRel", accessor_obj, related_obj.get_accessor_name())# 上面accessor_obj 相當(dāng)于 customer.enrollment_setif hasattr(accessor_obj, 'select_related'): # slect_related() == all()target_objs = accessor_obj.select_related() # .filter(**filter_coditions)# target_objs 相當(dāng)于 customer.enrollment_set.all() sub_ul_ele = "<ul style='color:red'>"for o in target_objs:li_ele = '''<li> %s: %s </li>''' % (o._meta.verbose_name, o.__str__().strip("<>"))sub_ul_ele += li_elesub_ul_ele += "</ul>"ul_ele += sub_ul_eleelif hasattr(obj, related_obj.get_accessor_name()): # hassattr(customer,'enrollment_set')accessor_obj = getattr(obj, related_obj.get_accessor_name())# 上面accessor_obj 相當(dāng)于 customer.enrollment_setif hasattr(accessor_obj, 'select_related'): # slect_related() == all()target_objs = accessor_obj.select_related() # .filter(**filter_coditions)# target_objs 相當(dāng)于 customer.enrollment_set.all()else:print("one to one i guess:", accessor_obj)target_objs = accessor_objif len(target_objs) > 0:# print("\033[31;1mdeeper layer lookup -------\033[0m")# nodes = recursive_related_objs_lookup(target_objs,model_name) nodes = self.display_all_related_objs(target_objs)ul_ele += nodesul_ele += "</ul>"return ul_eledef batch_remove(self,request,queryset):queryset.delete()# relected_obj=self.display_all_related_objs(queryset)# # print(html_str)# return render(request,'dolphin/dol_delete.html',locals())batch_remove.short_description = "批量刪除"@propertydef new_actions(self):temp=[]temp.append(ModelDolphin.batch_remove)temp.extend(self.actions)return tempdef set_pop_tags(self,forms):for bfield in forms:if isinstance(bfield.field,ModelMultipleChoiceField) or isinstance(bfield.field,ModelChoiceField):bfield.is_pop=True#兩種方式獲取類 一對多 或者多對多 的關(guān)聯(lián)表 模型# filter_field_obj = self.model._meta.get_field(bfield.name).related_modelfilter_field_obj=bfield.field.queryset.model# print("----",bfield.name,type(bfield.name),filter_field_obj)# print("+++++++++",filter_field_obj2)related_app_label = filter_field_obj._meta.app_labelrelated_model_name = filter_field_obj._meta.model_name_url=reverse("{related_app_label}_{related_model_name}_add".format(related_app_label=related_app_label,related_model_name=related_model_name))bfield.url=_url+"?pop_res_id={0}".format(bfield.auto_id )# if isinstance(bfield.field,BooleanField):# print(bfield)# bfield.is_checkbox=Truereturn formsdef get_modelform_class(self):if not self.modelform_class:class ModelFormDemo(ModelForm):class Meta:model = self.modelfields = "__all__"# exclude = ("is_delete",)return ModelFormDemoelse:return self.modelform_classdef get_search_condition(self,request):key_word = request.GET.get("key_words","")self.key_word=key_word# 獲取當(dāng)前列表中的所有數(shù)據(jù) search_connection = Q()search_connection.connector = "OR"for search_field in self.search_fields:search_connection.children.append(("{field}__contains".format(field=search_field), key_word))return search_connectiondef get_filter_condition(self,request):filter_condition = Q() #默認(rèn)且for filter_field, val in request.GET.items():if filter_field in self.list_filter:filter_condition.children.append((filter_field, val))return filter_conditiondef list_view(self, request):if request.method=="POST":action= request.POST.get("action")selected_pk=request.POST.getlist("selected_pk")warning_flag=Falseif hasattr(self,action) and selected_pk:action_func=getattr(self,action)queryset = self.model.objects.filter(pk__in=selected_pk)action_func(request, queryset)else:warning_flag=Truesearch_condition=self.get_search_condition(request)#獲取 第一次關(guān)鍵詞篩選的條件get("selected_pk")filter_condition=self.get_filter_condition(request)#獲取 第二次過濾的條件# data_list=self.model.objects.all().filter(search_connection)#第一次篩選后的所有數(shù)據(jù) 通過關(guān)鍵詞查詢data_list = self.model.objects.get_queryset().filter(search_condition).filter(filter_condition) # 解決異常 UnorderedObjectListWarningshowlist=ShowList(self,data_list,request)#拿到表名tablename=self.model._meta.verbose_name_plural#構(gòu)建一個(gè)添加數(shù)據(jù)連接add_url=self.reverse_url("add")return render(request, "dol_list.html", locals())#可以是 locals()def add_view(self, request):ModelFormDemo=self.get_modelform_class()list_url=self.reverse_url('list')forms =self.set_pop_tags(ModelFormDemo())if request.method=="POST":forms=self.set_pop_tags(ModelFormDemo(request.POST))if forms.is_valid():obj=forms.save()pop_res_id=request.GET.get("pop_res_id",None)if pop_res_id:res={"pk":obj.pk,"text":str(obj),"pop_res_id":pop_res_id}return render(request, "dol_pop.html", {"res":res})else:return redirect(list_url)return render(request, "dol_add.html", locals())def change_view(self, request, id):ModelFormDemo = self.get_modelform_class()edit_obj=self.model.objects.filter(pk=id).first()list_url = self.reverse_url('list')if request.method=="POST":forms=ModelFormDemo(request.POST,instance=edit_obj)if forms.is_valid():forms.save()return redirect(list_url)return render(request, "dol_change.html", locals())forms = ModelFormDemo(instance=edit_obj)return render(request, "dol_change.html", locals())def delete_view(self, request, id):url_list = self.reverse_url('list')delete_obj=self.model.objects.filter(pk=id)print("####",delete_obj)if request.method=="POST":delete_obj.delete()return redirect(url_list)delete_obj_detail=self.display_all_related_objs(delete_obj)return render(request, "dol_delete.html", locals())@propertydef get_urls2(self):app_label = self.model._meta.app_labelmodel_name = self.model._meta.model_nametemp = []# print("#"*20)temp.append(re_path(r'^$', self.list_view,name="{app_label}_{model_name}_list".format(app_label=app_label,model_name=model_name)))temp.append(re_path(r'^add/$', self.add_view,name="{app_label}_{model_name}_add".format(app_label=app_label,model_name=model_name)))temp.append(re_path(r'^(\d+)/change/$', self.change_view,name="{app_label}_{model_name}_change".format(app_label=app_label,model_name=model_name)))temp.append(re_path(r'^(\d+)/delete/$', self.delete_view,name="{app_label}_{model_name}_delete".format(app_label=app_label,model_name=model_name)))return temp@propertydef urls2(self):return self.get_urls2, None, None class DolphinSite(object):def __init__(self,name='admin'):self._registry={}def get_urls(self):temp=[]for model,dolphin_class_obj in self._registry.items():app_name=model._meta.app_labelmodel_name=model._meta.model_nametemp.append(path('{0}/{1}/'.format(app_name,model_name),dolphin_class_obj.urls2),)return temp@propertydef urls(self):return self.get_urls(),None,Nonedef register(self, model, dolphin_class=None, **options):if not dolphin_class:dolphin_class=ModelDolphinself._registry[model] = dolphin_class(model, self)#放進(jìn)字典里面 site=DolphinSite() server.Dolphin.py?
轉(zhuǎn)載于:https://www.cnblogs.com/Mengchangxin/p/10468878.html
總結(jié)
以上是生活随笔為你收集整理的类Xadmin插件--海豚插件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 宝沃汽车加油冒黑烟,什么原因?
- 下一篇: DLNg[结构化ML项目]第二周迁移学习