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())