1. Django项目启动 自动加载文件 制作启动文件 1. 注册strak 在apps.py 类里面增加如下 def ready(self): from django.utils.module_loading import autodiscover_modules autodiscover_modules("stark") 2. 在已经注册的app中创建stark.py文件 加载 2. 在stark中模仿AdminSite ModelAdmin类写代码 注册自己的类 class StarkConfig(object): def __init__(self,model_class,site): self.model_class = model_class self.site = site class StarkSite(object): def __init__(self): self._registey = {} def register(self,model_class,stark_config_class=None): if not stark_config_class: stark_config_class = StarkConfig self._registey[model_class] = stark_config_class(model_class,self) site = StarkSite() 3. 将注册的类自动生成url - urls.py from stark.service import v1 urlpatterns = [ url(r‘^stark/‘, v1.site.urls), ] - 为每个类生成4个url v1.py class StarkConfig(object): def __init__(self,model_class,site): self.model_class = model_class self.site = site def get_urls(self): app_model_name = (self.model_class._meta.app_label,self.model_class._meta.model_name,) url_patterns = [ url(r‘^$‘,self.changelist_view,name="%s_%s_changlist" %app_model_name), url(r‘^add/$‘,self.add_view,name="%s_%s_add" %app_model_name), url(r‘^(\d+)/delete/$‘,self.delete_view,name="%s_%s_delete" %app_model_name), url(r‘^(\d+)/change/$‘,self.change_view,name="%s_%s_chang" %app_model_name), ] return url_patterns @property def urls(self): return self.get_urls() def changelist_view(self,request,*args,**kwargs): return HttpResponse(‘列表‘) def add_view(self,request,*args,**kwargs): return HttpResponse(‘添加‘) def delete_view(self,request,nid,*args,**kwargs): return HttpResponse(‘删除‘) def change_view(self,request,nid,*args,**kwargs): return HttpResponse(‘修改‘) class StarkSite(object): def __init__(self): self._registey = {} def register(self,model_class,stark_config_class=None): if not stark_config_class: stark_config_class = StarkConfig self._registey[model_class] = stark_config_class(model_class,self) def get_urls(self): url_pattern = [] for model_class,stark_config_obj in self._registry.items(): app_name = model_class._meta.app_label model_name = model_class._meta.model_name curd_url = url(r‘^%s/%s/‘ %(app_name,model_name,) , (stark_config_obj.urls,None,None)) url_pattern.append(curd_url) return url_pattern @property def urls(self): return (self.get_urls(),None,‘stark‘) site = StarkSite() 4. 列表页面展示 - v1.py def changelist_view(self,request,*args,**kwargs): # 处理表头 head_list = [] for field_name in self.list_display: if isinstance(field_name,str): # 根据类和字段名称,获取字段对象的verbose_name verbose_name = self.model_class._meta.get_field(field_name).verbose_name else: verbose_name = field_name(self,is_header=True) head_list.append(verbose_name) # 处理表中的数据 # [ UserInfoObj,UserInfoObj,UserInfoObj,UserInfoObj,] # [ UserInfo(id=1,name=‘alex‘,age=18),UserInfo(id=2,name=‘alex2‘,age=181),] data_list = self.model_class.objects.all() new_data_list = [] for row in data_list: # row是 UserInfo(id=2,name=‘alex2‘,age=181) # row.id,row.name,row.age temp = [] for field_name in self.list_display: if isinstance(field_name,str): val = getattr(row,field_name) # # 2 alex2 else: val = field_name(self,row) temp.append(val) new_data_list.append(temp) return render(request,‘stark/changelist.html‘,{‘data_list‘:new_data_list,‘head_list‘:head_list}) - shark.py class UserInfoConfig(v1.StarkConfig): def checkbox(self,obj=None,is_header=False): if is_header: return ‘选择‘ return mark_safe(‘<input type="checkbox" name="pk" value="%s" />‘ %(obj.id,)) def edit(self,obj=None,is_header=False): if is_header: return ‘编辑‘ return mark_safe(‘<a href="/edit/%s">编辑</a>‘ %(obj.id,)) list_display = [checkbox,‘id‘,‘name‘,edit] 4. 显示增加按钮 - 先判断是否显示,再通过反向解析生成增加链接 - 后端 # 是否显示增加按钮 show_add_btn = True def get_show_btn(self): return self.show_add_btn return render(request, ‘stark/changelist.html‘, {‘data_list‘: new_data_list, ‘head_list‘: head_list,"add_url":self.get_add_url(),"show_add_btn":self.get_show_btn()}) - 前端 {% if show_add_btn %} <a class="btn btn-primary" href="{{ add_url }}">增加</a> {% endif %} 5. 增加内容页面 1. 通过ModelForm创建公共类 显示和提交 - 后端 def add_view(self, request, *args, **kwargs): class AddTable(ModelForm): class Meta: model = self.model_class fields = "__all__" if request.method == "GET": form = AddTable() return render(request,"stark/add_view.html",{"form":form}) else: form = AddTable(request.POST) if form.is_valid(): form.save() return redirect(self.get_list_url()) else: return render(request, "stark/add_view.html", {"form": form}) - 前端 <form method="post" novalidate> {% csrf_token %} {{ form.as_p }} <input type="submit" value="提交"> </form> 2. 升级 在子类自定义ModelForm类 子类之后可以自定义类 - v1.py model_form_class = None def get_model_form_class(self): if self.model_form_class: return self.model_form_class else: #方式一: # class AddTable(ModelForm): # class Meta: # model = self.model_class # fields = "__all__" # return AddTable #方式二: meta = type("Meta",(object,),{"model":self.model_class,"fields":"__all__"}) AddTable = type("AddTable",(ModelForm,),{"Meta":meta}) return AddTable def add_view(self, request, *args, **kwargs): model_form_class = self.get_model_form_class() if request.method == "GET": form = model_form_class() return render(request,"stark/add_view.html",{"form":form}) else: form = model_form_class(request.POST) if form.is_valid(): form.save() return redirect(self.get_list_url()) else: return render(request, "stark/add_view.html", {"form": form}) - stark.py class UserInfoModelForm(ModelForm): class Meta: model = models.UserInfo fields = ["name","password"] error_messages = { "name":{ ‘required‘:‘用户名不能为空‘ } } class UserInfoConfig(v1.StarkConfig): model_form_class = UserInfoModelForm 6. 修改 和 删除 def change_view(self, request, nid, *args, **kwargs): obj = self.model_class.objects.filter(pk=nid).first() if not obj: return redirect(self.get_list_url()) model_form_class = self.get_model_form_class() if request.method == "GET": form = model_form_class(instance=obj) return render(request,"stark/change_view.html",{"form":form}) else: form = model_form_class(instance=obj,data=request.POST) if form.is_valid: form.save() return redirect(self.get_list_url()) return render(request,"stark/change_view.html",{"form":form}) def delete_view(self, request, nid, *args, **kwargs): self.model_class.objects.filter(pk=nid).delete() return redirect(self.get_list_url())