一、url的分发练习
from django.conf.urls import url from django.contrib import admin from django.shortcuts import HttpResponse def index(request): return HttpResponse("首页") def add(request): #add视图函数 return HttpResponse("add") def list_view(request): #list_view视图函数 return HttpResponse("list_view") def change(request,id): #change视图函数 return HttpResponse("change") def delete(request,id): #delete视图函数 return HttpResponse("delete") def get_urls2(): #url的二级分发函数 temp=[ url("^add/$",add), url("^$",list_view), url("^(\d+)/change/$",change), url("^(\d+)/delete/$",delete), ] return temp def get_urls(): temp=[] for model,model_class_obj in admin.site._registry.items(): # 模型类:该模型类的配置类对象 {Book:ModelAdmin(Book),Publish:ModelAdmn(Publish),....} app_name=model._meta.app_label #得到应用名 model_name=model._meta.model_name temp.append(url(r"%s/%s/"%(app_name,model_name),(get_urls2(),None,None))) #url做分发,后面跟元组,元组第一项为一个列表 return temp from stark.service.sites import site urlpatterns = [ url(r'^admin/', admin.site.urls), url(r"^stark",(get_urls(),None,None)) ]
二、实现stark组件
app01应用的models.py文件:
from django.db import models class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() def __str__(self): return self.name class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() def __str__(self): return self.name class Book(models.Model): nid = models.AutoField(primary_key=True,verbose_name="编号") title = models.CharField( max_length=32,verbose_name="名称") publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2,verbose_name="价格") # 与Publish建立一对多的关系,外键字段建立在多的一方 publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) # 与Author表建立多对多的关系,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表 authors=models.ManyToManyField(to='Author',) def __str__(self): return self.title #执行下面python语句生成相关表(数据迁移) # python3 manage.py makemigrations # python3 manage.py migrate
项目下的settings.py文件设置:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', "app02.apps.App02Config", "stark.apps.StarkConfig", ] STATIC_URL = '/static/' STATICFILES_DIRS=[ os.path.join(BASE_DIR,"static") ]
项目的urls.py文件:
from django.conf.urls import url from django.contrib import admin from stark.service.sites import site urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^stark/', site.urls), #模拟admin的实现方式,在stark目录后面进行分发 ]
app01应用的stark.py文件对app01的应用表进行注册:
from stark.service.sites import site,ModelStark from app01.models import Book from app01.models import Publish from app01.models import Author class BookConfig(ModelStark): # def display_authors(self, obj=None,is_header=False): #显示多对多字段,单独定义函数实现方式 # # if is_header: # return "作者" # s=[] # for author in obj.authors.all(): # s.append(author.name) # # return " ".join(s) list_display = ["nid","title","price","publish","authors",] # list_display = ["nid","title","price","publish",display_authors] site.register(Book,BookConfig) site.register(Publish) site.register(Author)
项目下的stark目录下apps.py定义执行各个应用的stark.py:
from django.apps import AppConfig from django.utils.module_loading import autodiscover_modules class StarkConfig(AppConfig): name = 'stark' def ready(self): autodiscover_modules('stark') # 执行每一个app下的stark.py
项目下的stark目录下service目录下sites.py定义对用户访问url的分发:
from django.conf.urls import url from django.shortcuts import HttpResponse, render from django.utils.safestring import mark_safe class ModelStark(): #将增,删,改,查写到ModelStark类中,这样谁调用类中的功能,self.model就是用户访问的表 list_display = ["__str__", ] def __init__(self, model, site): self.model = model self.site = site def edit(self, obj=None, is_header=False): if is_header: return "操作" #表头返回 "操作" return mark_safe("<a href='%s/change'>编辑</a>" % obj.pk) #mark_safe会识别返回的html标签 def delete(self, obj=None, is_header=False): if is_header: return "操作" return mark_safe("<a href='%s/delete'>删除</a>" % obj.pk) def checkbox(self, obj=None, is_header=False): if is_header: return "选择" return mark_safe("<input type='checkbox' pk=%s>" % obj.pk) #在对应位置显示多选框 def add(self, request): return HttpResponse("add") def new_list_display(self): #新的显示样式,这样所有表的显示都有多选框,编辑和删除操作 temp = [] temp.append(ModelStark.checkbox) temp.extend(self.list_display) temp.append(ModelStark.edit) temp.append(ModelStark.delete) return temp def list_view(self, request): print(self.model) data_list = self.model.objects.all() print("list_display", self.list_display) # ["nid","title","price",edit] # 处理表头 header_list = [] for field in self.new_list_display(): if isinstance(field, str): #判断field是字符串类型 if field == "__str__": #字段是__str__ val = self.model._meta.model_name.upper() #表头显示表名的大写字母 else: field_obj = self.model._meta.get_field(field) val = field_obj.verbose_name #得到字段的verbose_name,定义后可以显示中文 else: val = field(self, is_header=True) #field是函数,执行函数 header_list.append(val) # 处理表单数据 new_data_list = [] for obj in data_list: temp = [] for field in self.new_list_display(): # ["nid","title","price","authors",edit] ['__str__'] ["title","price"] if isinstance(field, str): try: from django.db.models.fields.related import ManyToManyField field_obj = self.model._meta.get_field(field) #得到field的字段对象 if isinstance(field_obj, ManyToManyField): #判断是多对多关系的字段 l = [] for i in getattr(obj, field).all(): #.all()得到所有的对象,否则none l.append(str(i)) val = ",".join(l) else: val = getattr(obj, field) print("val", val) except Exception as e: val = getattr(obj, field) #反射,取到字段名 else: val = field(self, obj) temp.append(val) new_data_list.append(temp) return render(request, "list_view.html", locals()) def change(self, request, id): return HttpResponse("change") def delete_view(self, request, id): return HttpResponse("delete_view") def get_urls2(self): temp = [ url("^add/$", self.add), url("^$", self.list_view), url("^(\d+)/change/$", self.change), url("^(\d+)/delete/$", self.delete_view), ] return temp @property def urls2(self): return self.get_urls2(), None, None class StarkSite(): def __init__(self, ): self._registry = {} # 一级分发 def get_urls(self): temp = [] for model, model_class_obj in self._registry.items(): # {Book:ModelAdmin(Book),Publish:ModelAdmn(Publish),....} app_name = model._meta.app_label model_name = model._meta.model_name temp.append(url(r"%s/%s/" % (app_name, model_name), model_class_obj.urls2)) #接着二级分发 return temp @property def urls(self): return self.get_urls(), None, None def register(self, model, admin_class=None, **options): if not admin_class: admin_class = ModelStark self._registry[model] = admin_class(model, self) site = StarkSite()
list_view.html页面:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/bs/css/bootstrap.css"> </head> <body> <h3>查看数据</h3> <div> <div> <div> <table class="table table-bordered table-hover table-striped"> <thead> <tr> {% for foo in header_list %} <th>{{ foo }}</th> {% endfor %} </tr> </thead> <tbody> {% for new_data in new_data_list %} <tr> {% for foo in new_data %} <td>{{ foo }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> </div> </div> </div> </body> </html>
三、显示多对多字段的另一种方法
stark.py注册表时自定义函数:
class BookConfig(ModelStark): def display_authors(self, obj=None,is_header=False): #显示多对多字段 if is_header: return "作者" s=[] for author in obj.authors.all(): s.append(author.name) return " ".join(s) list_display = ["nid","title","price","publish",display_authors]
sites.py里面的ModelStark类定义的list_view
def list_view(self, request): print(self.model) data_list = self.model.objects.all() print("list_display", self.list_display) # ["nid","title","price",edit] # 处理表头 # header_list=["ID","名称","价格"] header_list=[] for field in self.new_list_display(): if isinstance(field,str): if field=="__str__": val=self.model._meta.model_name.upper() else: field_obj=self.model._meta.get_field(field) val=field_obj.verbose_name else: val=field(self,is_header=True) header_list.append(val) # 处理表单数据 new_data_list = [] for obj in data_list: temp = [] for field in self.new_list_display(): # ["nid","title","price","authors",edit] ['__str__'] ["title","price"] if isinstance(field,str): val = getattr(obj, field) else: val=field(self,obj) temp.append(val) new_data_list.append(temp)
页面显示效果图:
原文地址:http://blog.51cto.com/qidian510/2129950
时间: 2024-10-06 07:05:27