一、相关知识点回顾

1、什么是反射?

    可以用字符串的方式去访问对象的属性

 2、反射有四种方法?

  1. hasattr(object,name):判断一个对象是不是有name属性或者方法
  2. getattr:获取对象的属性或者方法,  需要注意的是,如果返回的是对象的方法,返回出来的是对象的内存地址, 如果需要运行这个方法,可以在后面添加一对()
  3. setattr:给对象的属性赋值,如果属性不存在,先创建后赋值
  4. delattr:删除该对象指定的一个属性

3、创建ModelForm的两种方式

  1. # 方式一定义ModelForm
  2. class TestModelForm(ModelForm):
  3. class Meta:
  4. model = self.model_class
  5. fields = "__all__"
  6.  
  7. 方式二定义
  8. Meta = type("Meta", (object,), {"model": self.model_class, "fields": "__all__"})
  9. TestModelForm = type("TestModelForm", (ModelForm,), {"Meta": Meta})

二、具体流程以及相关知识点

1、路由系统

让url对应视图,这时的视图可以是一个元组,元组的里面放三个参数,第一个是个列表,这两种表示方式都是一样的,用那种都行

namespace的用法如下

  1. v => ([],None,None) namespace(是第三个参数),用于区分相同nameurl,通过namespaceurl添加一个前缀

如图:

namespace

2.流程:

1、一旦运行的时候都会去执行admin.py ,现在我们让你开始执行stark.py 文件,加上下面的这些(参考的是admin的源码,在每一个admin文件的里面点击进入)

  1. from django.utils.module_loading import autodiscover_modules
  2.  
  3. class StarkConfig(AppConfig):
  4. name = 'stark' #应用名称
  5.  
  6. def ready(self):
  7. autodiscover_modules('stark') #在应用中创建的py文件和这个名字一样

切记一定要在sessings中配置一下:

  1. 'app02.apps.App02Config',
  2. 'stark.apps.StarkConfig',

2、然后再每个应用下面也创建一个stark.py的文件
       这样就像admin一样了,就开始执行site.redister了

3、这时候还没有site呢,需要自己实例化一个site
       在应用下创建一个service的文件夹,再创建一个v1.py文件,在里面写代码

4、在stark里面注册

需要注意的是:

  1. v1.site.register(models.UserInfo)
  2. -> 执行 StackConfig changelist_view方法/add_view....
  3.  
  4. class UserInfoConfig(v1.StarkConfig):
  5. def changelist_view(self,request,*args,**kwargs):
  6. return HttpResponse('你猜我是谁?')
  7.  
  8. v1.site.register(models.UserInfo,UserInfoConfig)
  9.  
  10. ---> 优先查看自己config中是否存在方法,不存在则执行基类 StackConfig changelist_view方法/add_view....

如图:

5、注册完成之后走urls。仿照admin的urls.。。。v1.site.urls
6、完了在v1.py中写代码

  1. class StarkSite(object):
  2. def __init__(self):
  3. self._registry ={} #放置处理请求对应关系
  4. '''
  5. _registry = {
  6. models.Role: StarkConfig(models.Role,v1.site),
  7. models.UserInfo: StarkConfig(models.UserInfo,v1.site)
  8. models.UserType: StarkConfig(models.UserType,v1.site)
  9. models.Article: StarkConfig(models.Article,v1.site)
  10. }
  11. '''
  12. def register(self,model_class,stark_config_class=None):
  13. if not stark_config_class:
  14. '''stark_config_class是类对象,如果没有这个类就重新赋值,去执行StarkConfig'''
  15. stark_config_class = StarkConfig
  16. self._registry[model_class] = stark_config_class(model_class,self)
  17. #如果用户自己传进去类了,就用自己的,自己的需要继承StarkConfig。如果自己没有就找基类的,自己有就用自己的
  18.  
  19. def get_urls(self):
  20. url_list = []
  21. for model_calss,stark_config_obj in self._registry.items():
  22. app_name = model_calss._meta.app_label#应用名称
  23. model_name = model_calss._meta.model_name#表的名称
  24. cur_url = url(r'^{0}/{1}/'.format(app_name,model_name),(stark_config_obj.urls,None,None))
  25. #这是的stark_config_obj是上面StarkConfig的实例对象。stark_config_obj.urls就会去找上面类的urls
  26. url_list.append(cur_url)
  27. return url_list
  28. @property #吧方法当属性来用
  29. def urls(self):
  30. return (self.get_urls(),None,'stark') #第三个参数是namesapce

动态生成类名和应用名图示:

在v1里面有两个类

  1. - StarkConfig,用于为每一个类生成URL对应关系,并编写视图函数处理用户请求。
  2. [
  3. ^$ -> self.changelist_view
  4. ^add/$ -> self.add_view
  5. ^delete/$ -> self.delete_view
  6. ^change/$ -> self.dchange_view
  7. ]
  8.  
  9. - StarkSite
  10. 是一个容器,用于放置处理请求对应关系。
  11. {
  12. model.UserInfo: UserInfoConfig(model.UserInfo,self),
  13. model.UserType: StarkConfig(model.UserType,self),
  14. }

具体来写:当然前面的StarkSite类已经写过了,那我们来看看StarkConfig这个类

以下的功能实现都是在StarkConfig这个类里面的

功能实现一:展示页面,让页面上动态显示表格

  1. class StarkConfig(object):
  2. list_display = []
  3. def __init__(self, model_class, site):
  4. self.model_class = model_class
  5. self.site = site
  6. def change_list_views(self,request,*args,**kwargs):
  7. data_list = self.model_class.objects.all()
  8. '''展示th的信息'''
  9. head_list = []
  10. for field_name in self.list_display:
  11. if isinstance(field_name,str):
  12. verbose_name = self.model_class._meta.get_field(field_name).verbose_name
  13. else:
  14. verbose_name = field_name(self,is_header=True)
  15. # yield {"verbose_name":verbose_name}
  16. head_list.append(verbose_name)
  17.  
  18. '''展示td的信息'''
  19.  
  20. # [["id","name"],["id","name"],["id","name"],]
  21. new_data_list = []
  22. for row in data_list:
  23. temp = []
  24. for field_name in self.list_display:
  25. if isinstance(field_name,str):
  26. #如果是字符串类型的就是用getattr的方式,因为对象不能.字符串
  27. val = getattr(row,field_name)
  28. else:
  29. val = field_name(self,row)
  30. temp.append(val)
  31. # yield {"val":val}
  32. new_data_list.append(temp)
  33. return render(request, "stark/change_list_views.html", {"data_list":new_data_list,"head_list":head_list})

在stark.py 中

  1. strak.py
  2. print("sssss6666666")
  3. from app01 import models
  4. from stark.service import v1
  5. from django.utils.safestring import mark_safe
  6. class UserInfoConfig(v1.StarkConfig):
  7. def checkbox(self,obj=None,is_header=False):
  8. if is_header:
  9. return "选择"
  10. return mark_safe("<input type='checkbox' name='zzzz' value='%s'/>"%obj.id)
  11.  
  12. def edit(self,obj=None,is_header=False):
  13. if is_header:
  14. return "操作"
  15. return mark_safe("<a href='edit/%s'>编辑</a>"%obj.id)
  16. list_display = [checkbox,"id","name",edit]
  17.  
  18. v1.site.register(models.UserInfo,UserInfoConfig)
  19. v1.site.register(models.Role,UserInfoConfig)
  20. v1.site.register(models.UserType)

 功能二:当然我们现在把按钮是自己定制的,有与编辑,删除等都是我们很常用的,所以我们可以搞成默认的。在StarkConfig类里写

  1. # ===============吧删除,编辑,复选框设置默认按钮==================
  2.  
  3. def checkbox(self,obj=None,is_header=False):
  4. if is_header:
  5. return "选择"
  6. return mark_safe("<input type='checkbox' name='zzzz' value='%s'/>"%obj.id)
  7.  
  8. def edit(self,obj=None,is_header=False):
  9. if is_header:
  10. return "操作"
  11. return mark_safe("<a href='%s'>编辑</a>"%(self.get_change_url(obj.id),))
  12.  
  13. def delete(self,obj=None,is_header=False):
  14. if is_header:
  15. return "删除"
  16. #动态跳转路径,反向解析,因为每次都要用到,我们可以吧它封装到一个函数
  17. return mark_safe("<a href='%s'>删除</a>"%self.get_delete_url(obj.id))
  18.  
  19. #做默认的删除和编辑。对这个方法重写的时候可以吧权限管理加进去,
  20. # 当它都什么权限的时候显示什么按钮。
  21. def get_list_display(self):
  22. data = []
  23. if self.list_display:
  24. data.extend(self.list_display) #在新的列表里面吧list_display扩展进来
  25. data.append(StarkConfig.edit) #因为是默认的,直接在类里面去调用edit
  26. data.append(StarkConfig.delete)
  27. data.insert(0,StarkConfig.checkbox)
  28. return data

 功能三:默认显示添加按钮

  1. show_add_btn = True
  2. # ======这个方法可自定制(如果把show_add_btn设置为False就不会显示添加按钮)=====
  3. def get_show_add_btn(self):
  4. return self.show_add_btn

 功能四:当点击编辑,删除,添加按钮的时候的跳转路径,动态生成

  1. return render(request, "stark/change_list_views.html",{"add_url":self.get_add_url(),"show_add_btn":self.get_show_add_btn()})

利用反向解析reverse

  1. # =================url相关,reverse反向解析=============
  2. def get_change_url(self,nid):
  3. name = "stark:%s_%s_change"%(self.model_class._meta.app_label,self.model_class._meta.model_name)
  4. edit_url = reverse(name,args=(nid,)) #反向解析只要找到他的name属性,就会找到他对应的路径
  5. return edit_url
  6.  
  7. def get_add_url(self):
  8. name = "stark:%s_%s_add" % (self.model_class._meta.app_label, self.model_class._meta.model_name)
  9. edit_url = reverse(name)
  10. return edit_url
  11.  
  12. def get_delete_url(self, nid):
  13. name = "stark:%s_%s_delete" % (self.model_class._meta.app_label, self.model_class._meta.model_name)
  14. edit_url = reverse(name,args=(nid,))
  15. return edit_url
  16.  
  17. def get_list_url(self):
  18. name = "stark:%s_%s_changelist" % (self.model_class._meta.app_label, self.model_class._meta.model_name)
  19. edit_url = reverse(name)
  20. return edit_url

 功能五:添加,删除,编辑功能(利用MOdelForm)

  1. model_form_class=None
  2. def get_model_form_class(self):
  3. if self.model_form_class: #如果自己定制了就用自己的,在这就什么也不返回了,如果没有自己定义就返回默认的这个Form
  4. return self.model_form_class
  5. # 方式一定义ModelForm
  6. # class TestModelForm(ModelForm):
  7. # class Meta:
  8. # model = self.model_class
  9. # fields = "__all__"
  10. # return TestModelForm
  11. # 方式二定义
  12. Meta = type("Meta", (object,), {"model": self.model_class, "fields": "__all__"})
  13. TestModelForm = type("TestModelForm", (ModelForm,), {"Meta": Meta})
  14. return TestModelForm
  15. def add_views(self,request,*args,**kwargs):
  16. model_form_class = self.get_model_form_class()
  17. if request.method=="GET":
  18. form = model_form_class()
  19. return render(request,"stark/add_view.html",{"form":form})
  20. else:
  21. form = model_form_class(request.POST)
  22. if form.is_valid():
  23. form.save()
  24. return redirect(self.get_list_url())
  25. else:
  26. return render(request, "stark/add_view.html", {"form": form})
  27.  
  28. def delete_view(self, request,nid, *args, **kwargs):
  29. self.model_class.objects.filter(pk=nid).delete()
  30. return redirect(self.get_list_url())
  31.  
  32. def change_views(self, request,nid, *args, **kwargs):
  33. model_form_class = self.get_model_form_class()
  34. obj = self.model_class.objects.filter(pk=nid).first()
  35. if not obj:
  36. return redirect(self.get_list_url())
  37. if request.method == "GET":
  38. form = model_form_class(instance=obj)
  39. return render(request, "stark/edit_view.html", {"form": form})
  40. else:
  41. form = model_form_class(data=request.POST,instance=obj)
  42. if form.is_valid():
  43. form.save()
  44. return redirect(self.get_list_url())
  45. else:
  46. return render(request, "stark/edit_view.html", {"form": form})

 功能六:额外扩展url

  1. # =============路由系统,对应相应的视图函数=====================
  2. def get_urls(self):
  3. app_model_name = (self.model_class._meta.app_label,self.model_class._meta.model_name)
  4. all_url = [
  5. url(r'^$', self.change_list_views,name="%s_%s_changelist"%app_model_name),
  6. url(r'^add/$', self.add_views,name="%s_%s_add"%app_model_name),
  7. url(r'^(\d+)/delete/$', self.delete_view,name="%s_%s_delete"%app_model_name),
  8. url(r'^(\d+)/change/$', self.change_views,name="%s_%s_change"%app_model_name),
  9. ]
  10. all_url.extend(self.extra_urls())
  11. return all_url
  12.  
  13. # ===========额外扩展url(用户可以进行随意扩展)==========
  14. def extra_urls(self):
  15. return []
  16.  
  17. @property
  18. def urls(self):
  19. return self.get_urls()

三、使用

  1. #!usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. print("sssss6666666")
  4. from app01 import models
  5. from django.conf.urls import url
  6. from stark.service import v1
  7. from django.shortcuts import render,HttpResponse,redirect
  8. from django.forms import ModelForm
  9. class UserInfoConfig(v1.StarkConfig):
  10. # 1、
  11. list_display = ["id","name","email"]
  12. # list_display = []
  13. # 2、
  14. def extra_urls(self):
  15. url_list =[
  16. url(r'^xxxx/$',self.func),
  17. ]
  18. return url_list
  19.  
  20. def func(self,request):
  21. return HttpResponse("我是额外添加的路径哦....")
  22. # 3、
  23. # show_add_btn=False #默认是True的,如果不让显示添加按钮可以自定制
  24.  
  25. # 4、
  26. def get_model_form_class(self):
  27. class MyModelForm(ModelForm):
  28. class Meta:
  29. model = self.model_class
  30. fields = "__all__"
  31. error_messages={
  32. "name":{"required":"用户名不能为空"},
  33. "email":{"invalid":"邮箱格式不正确"}
  34. }
  35. return MyModelForm
  36. # 5、
  37. def delete_view(self, request,nid, *args, **kwargs):
  38. if request.method=="GET":
  39. return render(request,"stark/delete_view.html",{"quxiao_url":self.get_list_url()})
  40. else:
  41. self.model_class.objects.filter(pk=nid).delete()
  42. return redirect(self.get_list_url())
  43. v1.site.register(models.UserInfo,UserInfoConfig)

  44. ===================================================
  45. class RoleConfig(v1.StarkConfig):
  46.  
  47. list_display = ["id","name"]
  48. # list_display = []
  49. def extra_urls(self):
  50. url_list =[
  51. url(r'^aaaa/$',self.func),
  52. ]
  53. return url_list
  54.  
  55. def func(self,request):
  56. return HttpResponse("我是额外添加的路径哦....")
  57.  
  58. # show_add_btn=False #默认是True的,如果不让显示添加按钮可以自定制
  59.  
  60. def get_model_form_class(self):
  61. class MyModelForm(ModelForm):
  62. class Meta:
  63. model = self.model_class
  64. fields = "__all__"
  65. error_messages={
  66. "name":{"required":"用户名不能为空"},
  67. }
  68. return MyModelForm
  69. v1.site.register(models.Role,RoleConfig)
  70. v1.site.register(models.UserType)

  71. ======================================================
  72. class HostConfig(v1.StarkConfig):
  73. def ip_port(self, obj= None,is_header=False):
  74. if is_header: #如果是True就返回的是th的,默认就是True
  75. return "自定义列"
  76. return "%s_%s"%(obj.id,obj.port,) #当是False的时候就返回的是td的
  77. list_display = ["id","name","ip","port",ip_port]
  78.  
  79. # =====扩展一个url路径======
  80. def extra_urls(self):
  81. url_list = [
  82. url(r'^report/$', self.report_view),
  83. ]
  84. return url_list
  85. def report_view(self,request):
  86. return HttpResponse("<h3>这是我给报表另外添加的一个路径</h3>")
  87. v1.site.register(models.Host,HostConfig)

四、总结:

  1. 注意:如果是在应用里面建的static文件,是不用再settings里面配置的,就可以用
  2. 需要知道的知识点
  3. 1for model_calss,stark_config_obj in self._registry.items():
  4. app_name = model_calss._meta.app_label#应用名称
  5. model_name = model_calss._meta.model_name#表的名称
  6. self.model_class._meta.get_field(field_name).verbose_name #得到字段的verbose_name
  7.  
  8. 2 if isinstance(field_name,str):
  9. #如果是字符串类型的就是用getattr的方式,因为对象不能.字符串
  10. val = getattr(row,field_name)
  11.  
  12. 3 for field_name in self.list_display:
  13. if isinstance(field_name,str):
  14. #如果是字符串类型的就是用getattr的方式,因为对象不能.字符串
  15. val = getattr(row,field_name)
  16. else: #如果不是字符串传进来的就是函数,所以得加括号调用函数
  17. val = field_name(field_name,row)
  18. temp.append(val)
  19. new_data_list.append(temp)
  20.  
  21. 4、吧方法当属性来用
  22. @property
  23. def urls(self):
  24. return self.get_urls()

一个小知识:
    1、什么时候加括号,什么时候不加括号
       当需要一个返回值的时候,就去执行函数,加括号
       当你不需要返回什么,直接告诉它函数名,让他去找这个函数名。就不用加括号

五、知识点补充

补充:用bootstrap修改样式

1、include:用include直接把单独的标签可以引入到html中。目的是减少代码的冗余

  1. {% include "stark/form.html" %}
  1. stark/form.html
  1. <form method="post" class="form-horizontal" novalidate>
  2. {% csrf_token %}
  3. {% for field in form %}
  4. <div class="col-sm-6">
  5. <div class="form-group">
  6. <label for="inputEmail3" class="col-sm-2 control-label">{{ field.label }}</label>
  7. <div class="col-sm-10">
  8. {{ field }}
  9. {{ field.errors.0 }}
  10. </div>
  11. </div>
  12. </div>
  13. {% endfor %}
  14. <div class="col-sm-offset-11 col-sm-1">
  15. <input type="submit" class="btn btn-primary" value="提交">
  16. </div>
  17. </form>

css样式

  1. .form-horizontal input[type="text"],input[type='email'],input[type='password'],input[type='checkbox'],input[type='number'],select,textarea{
  2. display: block;
  3. width: 100%;
  4. height: 34px;
  5. padding: 6px 12px;
  6. font-size: 14px;
  7. line-height: 1.42857143;
  8. color: #555;
  9. background-color: #fff;
  10. background-image: none;
  11. border: 1px solid #ccc;
  12. border-radius: 4px;
  13. -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  14. box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
  15. -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
  16. -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  17. transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
  18. }

补充二:需要优化的导入静态文件的方式

  1. {% load staticfiles %}
  2. <!DOCTYPE html>
  3. <html lang="en">
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  7. <meta name="viewport" content="width=device-width">
  8. <title>Title</title>
  9. <link rel="stylesheet" href="{% static '/bootstrap-3.3.7-dist/css/bootstrap.css'%} ">
  10. <link rel="stylesheet" href="{% static '/css/stark_form.css' %}">
  11. </head>
  12. <body>
  13. <h3>添加页面</h3>
  14. {% include "stark/form.html" %}
  15. </body>
  16. </html>

Django项目----快速实现增删改查组件(起步阶段!!!)的更多相关文章

  1. django之创建第8-1个项目-数据库之增删改查/数据库数据显示在html页面

    1.为test.DB数据库预先创建下面数据 1    张三    16    2015-01-02    12    李四    17    2015-01-04    13    王五    14  ...

  2. 基于django做增删改查组件,分页器组件

    增删改查组件 一.Djangoadmin的启发 二.基于Djangoadmin实现数据的增删改查 分页器组件 分页器组件的介绍以及源码解读 补充:源码下载,

  3. day84-仿照admin实现一个自定义的增删改查组件

    一.admin的使用 app01的admin.py文件: class BookConfig(admin.ModelAdmin): list_display=[] list_display_links= ...

  4. popup的简单应用举例(具体在增删改查组件中用到)以及补充的知识点

    一.首先说一下自执行函数 1. 立即执行函数是什么?也就是匿名函数 立即执行函数就是 声明一个匿名函数 马上调用这个匿名函数 2.popup的举例 点击,弹出一个新的窗口.保存完事,页面不刷新数据就返 ...

  5. Python学习---django之ORM的增删改查180125

    模型常用的字段类型参数 <1> CharField        #字符串字段, 用于较短的字符串.        #CharField 要求必须有一个参数 maxlength, 用于从数 ...

  6. Django基于类的增删改查,简单逻辑都不用写

    Django是Python中一个非常牛逼的web框架,他帮我们做了很多事,里边也提前封装了很多牛逼的功能,用起来简直不要太爽,在写网站的过程中,增删改查这几个基本的功能我们是经常会用到,Django把 ...

  7. Asp.net WebApi 项目示例(增删改查)

    1.WebApi是什么 ASP.NET Web API 是一种框架,用于轻松构建可以由多种客户端(包括浏览器和移动设备)访问的 HTTP 服务.ASP.NET Web API 是一种用于在 .NET ...

  8. Django之数据表增删改查

    Django数据增删改查: 上课代码 from django.shortcuts import render,HttpResponse # Create your views here. from a ...

  9. django -- ORM实现作者增删改查

    前戏 前面我们已经实现了出版社的增删改查,书的增删改查,书和出版社的对应关系.现在来写一下作者的增删改查和书的对应关系,那书和作者有什么关系呢?一个作者可以写多本书,一本书可以有多个作者,所以书和作者 ...

随机推荐

  1. docker私有仓库搭建和资源限制

    Docker 私有仓库的搭建 docker 私有仓库默认只支持https协议的访问  不支持http协议 如果需要允许通过http协议访问 必须手动修改配置文件 docker官方默认提供的仓库  提供 ...

  2. 2017-2018-2 20165236 实验四《Android开发基础》实验报告

    2017-2018-2 20165236 实验四<Android开发基础>实验报告 一.实验报告封面 课程:Java程序设计       班级:1652班       姓名:郭金涛     ...

  3. vue 上传图片 input=file

    一.逻辑 点击li触发事件chooseImage 即触发input标签事件photoChange input标签事件photoChange file返回的是如下变量 模拟上传表单方法 执行上传 二.代 ...

  4. abap对象的创建和调用。方法调用

    1: abap中创建类和创建对象,调用方法. *&---------------------------------------------------------------------* ...

  5. xtrabackup全库还原+binlog日志还原

    1.场景 mysql数据库误删某个库.误删表或者误删除数据 如下模拟图:备份策略定为每天凌晨进行全库备份,在B时间点进行了误操作以后,有两种恢复场景,一种是恢复到B时间点误操作前,一种是恢复到C时间点 ...

  6. php使用solr全文搜索引擎

    前言 本来以为网上已经有了类似博文,不想重复,可是一圈搜下来,都是一些内容不甚明了的文章,或者solr版本太过老,参考价值不高,更有甚者,直接拷贝的别人的内容.一篇博客,各大平台都能看到,也不见转载链 ...

  7. docker容器多服务(不推荐)

    1.最常用方式配置进程管理工具Supervisor 2.最简单的就是把多个启动命令放到一个启动脚本里面,启动的时候直接启动这个脚本 第一种方式: 1.构建基础镜像 FROM lmurawsk/pyth ...

  8. OpenShift Origin 基本命令

    用户管理 $ oc login #登陆$ oc logout #注销$ oc login -u system:admin -n default #以系统管理身份登陆并指定项目$ oc login ht ...

  9. python的py文件命名注意事项

    最近,在学习python爬虫时,用到各种库特性时,写小段代码,命名demo的py文件诸如:requests.py,json.py,csv.py.都会提示类似“module 'csv' has no a ...

  10. VS中去掉空格虚点

    Ctrl + R+W 可以在VS中添加或移除 空格虚点.