2018-10-19 15:42:15

2018-10-19 18:21:33

我觉得现在主要是学一种解决问题的思路,也就是逻辑或者说是算法!!!!

要有对代码的感触!要用面向对象对类进行封装!!Django源码写的就是很6

明天看完stark 然后整理Django !!周末啦!

过不久还得回学校!!!难得的在家清静!珍惜吧!

越努力,越幸运!!!永远不要高估自己!!

.model._meta的用法!

通过字段获取QuerySet对象

通过字段获取 app和表的名字!

model_name = self.model._meta.model_name
app_label = self.model._meta.app_label 这次新增了自定义过滤功能!
新学了上面两个知识点!
在源码上都有相应的注释!很好看懂!
不难就是有点绕!! server/stark.py
from django.conf.urls import url
from django.shortcuts import render, redirect
from django.urls import reverse
from django.utils.safestring import mark_safe
from django.forms import ModelForm
from stark.utils.page import Pagination
from django.db.models import Q
from django.db.models.fields.related import ForeignKey
from django.db.models.fields.related import ManyToManyField
import copy class ShowList(object):
# 这是一个配置类的对象初始化
def __init__(self, config, data_list, request):
self.config = config
self.data_list = data_list
self.request = request
# 分页
data_count = self.data_list.count()
current_page = int(self.request.GET.get("page", 1))
base_path = self.request.path
self.pagination = Pagination(current_page, data_count, base_path, self.request.GET, per_page_num=3, pager_count=11,)
self.page_data = self.data_list[self.pagination.start:self.pagination.end]
# actions 获取actions这个配置类的列表
self.actions = self.config.actions # [patch_init,] # 处理filter字段连接
def get_filter_linktags(self):
"""用了两次for循环,在算法上有点缀余!不过可以用类或函数封装只是懒-.-能力欠缺!"""
print("list_filter:", self.config.list_filter)
link_dic = {}
for filter_field in self.config.list_filter: # ["title","publish","authors",]
params = copy.deepcopy(self.request.GET)
cid = self.request.GET.get(filter_field, 0)
print("filter_field", filter_field) # "publish"
# 通过_meta.get_field方法,获取该表名对象
filter_field_obj = self.config.model._meta.get_field(filter_field) print("filter_field_obj", filter_field_obj)
print(type(filter_field_obj))
# print("rel...",filter_field_obj.rel.to.objects.all()) # 判断一下 如果是多对多或一对多类型的
if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField):
# 拿到表的所有QuerySet对象
data_list = filter_field_obj.rel.to.objects.all() # 【publish1,publish2...】
else:
# 这个则是自定义过滤字段
data_list = self.config.model.objects.all().values("pk", filter_field)
print("data_list", data_list) temp = []
# 处理 全部标签
if params.get(filter_field):
# 如果url如果存在参数 则del
del params[filter_field]
temp.append("<a href='?%s'>全部</a>" % params.urlencode())
else:
# 反之加上class 增加颜色
temp.append("<a class='active' href='#'>全部</a>") # 处理 数据标签
for obj in data_list:
# 循环列表中每个QuerySet的对象然后取到相应的值
if isinstance(filter_field_obj, ForeignKey) or isinstance(filter_field_obj, ManyToManyField):
pk = obj.pk
text = str(obj)
params[filter_field] = pk
else: # data_list= [{"pk":1,"title":"go"},....]
pk = obj.get("pk")
text = obj.get(filter_field)
params[filter_field] = text _url = params.urlencode()
if cid == str(pk) or cid == text:
link_tag = "<a class='active' href='?%s'>%s</a>" % (_url, text)
else:
link_tag = "<a href='?%s'>%s</a>" % (_url, text)
temp.append(link_tag) link_dic[filter_field] = temp
return link_dic # 获取下拉框 用户配置的action_list
def get_action_list(self):
temp = []
for action in self.actions:
# [{"name":""patch_init,"desc":"批量初始化"}]
temp.append({
"name": action.__name__,
"desc": action.short_description
})
return temp # 构建表头
def get_header(self):
header_list = []
print("header", self.config.new_list_play())
# [checkbox,"pk","name","age",edit ,deletes] 【checkbox ,"__str__", edit ,deletes】
for field in self.config.new_list_play(): if callable(field):
# header_list.append(field.__name__)
val = field(self.config, header=True)
header_list.append(val) else:
if field == "__str__":
header_list.append(self.config.model._meta.model_name.upper())
else:
# header_list.append(field)
val = self.config.model._meta.get_field(field).verbose_name
header_list.append(val)
return header_list # 构建表单数据
def get_body(self):
# 构建表单数据
new_data_list = []
for obj in self.page_data:
temp = []
for filed in self.config.new_list_play(): # ["__str__",] ["pk","name","age",edit]
if callable(filed):
val = filed(self.config, obj)
else:
field_obj = self.config.model._meta.get_field(filed)
if isinstance(field_obj, ManyToManyField):
# getattr()仅取到Object, 然后.all() 则可以取到对象
ret = getattr(obj, filed).all()
t = []
for obj in ret:
t.append(str(obj))
val = ",".join(t) else:
val = getattr(obj, filed)
if filed in self.config.list_display_links:
# "app01/userinfo/(\d+)/change"
_url = self.config.get_change_url(obj)
val = mark_safe("<a href='%s'>%s</a>" % (_url, val)) temp.append(val) new_data_list.append(temp)
return new_data_list class ModelStark(object):
# 默认的list_play[]
list_display = ["__str__", ]
list_display_links = []
modelform_class = None
search_fields = []
actions = []
list_filter = [] def __init__(self, model, site):
self.model = model
self.site = site # 默认的批量删除action
def patch_delete(self, request, queryset):
queryset.delete()
patch_delete.short_description = "批量删除" # 配置表头: 删除 编辑,复选框
def edit(self, obj=None, header=False):
"""编辑"""
if header:
return "操作"
# return mark_safe("<a href='%s/change'>编辑</a>"%obj.pk)
_url = self.get_change_url(obj)
return mark_safe("<a href='%s'>编辑</a>" % _url) def deletes(self, obj=None, header=False):
"""删除"""
if header:
return "操作"
# return mark_safe("<a href='%s/change'>编辑</a>"%obj.pk)
_url = self.get_delete_url(obj)
return mark_safe("<a href='%s'>删除</a>" % _url) def checkbox(self, obj=None, header=False):
"""复选框"""
if header:
return mark_safe('<input id="choice" type="checkbox">')
# value的值不能写死,
return mark_safe('<input class="choice_item" type="checkbox" name="selected_pk" value="%s">' % obj.pk) # 获取配置类的表头信息
def get_modelform_class(self):
"""获取表的配置类"""
if not self.modelform_class:
# 如果表的配置类为空
class ModelFormDemo(ModelForm):
class Meta:
model = self.model
fields = "__all__"
labels = {
""
}
return ModelFormDemo
else:
return self.modelform_class # 添加的视图函数
def add_view(self, request):
ModelFormDemo = self.get_modelform_class()
if request.method == "POST":
form = ModelFormDemo(request.POST)
if form.is_valid():
form.save()
return redirect(self.get_list_url()) return render(request, "add_view.html", locals()) form = ModelFormDemo() return render(request, "add_view.html", locals()) # 删除的视图函数
def delete_view(self, request, id):
url = self.get_list_url()
if request.method == "POST":
self.model.objects.filter(pk=id).delete()
return redirect(url)
return render(request, "delete_view.html", locals()) # 编辑的视图函数
def change_view(self, request, id):
ModelFormDemo = self.get_modelform_class()
edit_obj = self.model.objects.filter(pk=id).first()
if request.method == "POST":
form = ModelFormDemo(request.POST, instance=edit_obj)
if form.is_valid():
form.save()
return redirect(self.get_list_url())
return render(request, "add_view.html", locals())
form = ModelFormDemo(instance=edit_obj)
return render(request, "change_view.html", locals()) # 搜索的视图函数
def get_serach_conditon(self, request):
key_word = request.GET.get("q", "")
self.key_word = key_word
search_connection = Q()
if key_word:
# self.search_fields # ["title","price"]
search_connection.connector = "or"
# 用Q的这种添加方法可以添加字符串
for search_field in self.search_fields:
# search_field+"__contains" ----> title__contains="o" 就是title字段里面包含字母o的
search_connection.children.append((search_field + "__contains", key_word))
return search_connection # 过滤filter的视图函数
def get_filter_condition(self, request):
filter_condition = Q()
for filter_field, val in request.GET.items():
if filter_field in self.list_filter:
filter_condition.children.append((filter_field, val))
return filter_condition # 查看的视图函数
def list_view(self, request):
if request.method == "POST": # action
print("POST:", request.POST)
action = request.POST.get("action") # patch_init
selected_pk = request.POST.getlist("selected_pk")
action_func = getattr(self, action)
queryset = self.model.objects.filter(pk__in=selected_pk)
ret = action_func(request, queryset)
# return ret
# 获取search的Q对象
search_connection = self.get_serach_conditon(request) # 获取filter构建Q对象
filter_condition = self.get_filter_condition(request) # 筛选获取当前表所有数据
data_list = self.model.objects.all().filter(search_connection).filter(filter_condition) # 【obj1,obj2,....】 # 按这ShowList展示页面
showlist = ShowList(self, data_list, request) # 构建一个查看URL
add_url = self.get_add_url()
return render(request, "list_view.html", locals()) # 获取用户配置类里面的list_play[]
def new_list_play(self):
temp = []
temp.append(ModelStark.checkbox)
temp.extend(self.list_display)
if not self.list_display_links:
temp.append(ModelStark.edit)
temp.append(ModelStark.deletes)
return temp # 获取用户配置类里面的actions 这个列表
def new_actions(self):
temp=[]
temp.append(ModelStark.patch_delete)
temp.extend(self.actions)
return temp """把url进行反向解析,解耦到各自的函数中,函数中直接返回了对应的url"""
# 获取修改页面的url
def get_change_url(self, obj):
model_name = self.model._meta.model_name
app_label = self.model._meta.app_label _url = reverse("%s_%s_change" % (app_label, model_name), args=(obj.pk,)) return _url # 获删除改页面的url
def get_delete_url(self, obj):
model_name = self.model._meta.model_name
app_label = self.model._meta.app_label _url = reverse("%s_%s_delete" % (app_label, model_name), args=(obj.pk,)) return _url # 获取添加页面的url
def get_add_url(self): model_name = self.model._meta.model_name
app_label = self.model._meta.app_label _url = reverse("%s_%s_add" % (app_label, model_name)) return _url # 获取查看页面的url
def get_list_url(self): model_name = self.model._meta.model_name
app_label = self.model._meta.app_label _url = reverse("%s_%s_list" % (app_label, model_name)) return _url # 二级url分发函数
def get_urls_2(self):
temp = []
model_name = self.model._meta.model_name
app_label = self.model._meta.app_label
temp.append(url(r"^add/", self.add_view, name="%s_%s_add" % (app_label, model_name)))
temp.append(url(r"^(\d+)/delete/", self.delete_view, name="%s_%s_delete" % (app_label, model_name)))
temp.append(url(r"^(\d+)/change/", self.change_view, name="%s_%s_change" % (app_label, model_name)))
temp.append(url(r"^$", self.list_view, name="%s_%s_list" % (app_label, model_name)))
return temp @property
def urls_2(self):
print(self.model)
return self.get_urls_2(), None, None class StarkSite(object):
def __init__(self):
self._registry = {} def register(self, model, stark_class=None):
if not stark_class:
stark_class = ModelStark self._registry[model] = stark_class(model, self) # 一级分发url函数
def get_urls(self):
temp = []
for model, stark_class_obj in self._registry.items():
model_name = model._meta.model_name
app_label = model._meta.app_label
# 分发增删改查
temp.append(url(r"^%s/%s/" % (app_label, model_name), stark_class_obj.urls_2)) '''
url(r"^app01/userinfo/",UserConfig(Userinfo).urls_2),
url(r"^app01/book/",ModelStark(Book).urls_2), '''
return temp @property
def urls(self): return self.get_urls(), None, None # 创建stark的一个单例对象
site = StarkSite()

app01/stark.py

from stark.service.stark import site,ModelStark

from django.urls import reverse
from .models import * from django.utils.safestring import mark_safe from django.forms import ModelForm
from django.forms import widgets as wid class BookModelForm(ModelForm):
class Meta:
model = Book
fields = "__all__" labels={
"title":"书籍名称",
"price":"价格"
} from django.shortcuts import HttpResponse class BookConfig(ModelStark):
# 自定义展示列表
list_display = ["title","price","publishDate","publish","authors"]
# 自定义设置字段为连接
list_display_links = ["title"]
modelform_class=BookModelForm
# 自定义搜索字段
search_fields=["title","price"] def patch_init(self, request, queryset):
print(queryset)
queryset.update(price=123) return HttpResponse("批量初始化OK") patch_init.short_description = "批量初始化" # 自定义处理函数
actions = [patch_init] # 自定义筛选字段
list_filter=["title","publish","authors",] site.register(Book,BookConfig) site.register(Publish)
site.register(Author)
site.register(AuthorDetail)

list.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
<script src="/static/js/jquery-1.12.4.min.js"></script> <style>
.filter a{
text-decoration: none;
color: grey;
} .active{
color: rebeccapurple!important;
}
</style>
</head>
<body> <h4>数据列表</h4> <div class="container">
<div class="row">
<div class="col-md-9">
<a href="{{ add_url }}" class="btn btn-primary">添加数据</a> {% if showlist.config.search_fields %}
<form action="" class="pull-right">
<input class="form-control" style="display: inline-block;width:200px" type="text" name="q" value="{{ showlist.config.key_word }}"><button class="btn btn-default">search</button>
</form>
{% endif %} <form action="" method="post">
{% csrf_token %}
<select name="action" class="form-control" id="" style="width: 200px;margin: 8px 2px;display: inline-block;vertical-align: -1px">
<option value="">---------------</option>
{% for item in showlist.get_action_list %}
<option value="{{ item.name }}">{{ item.desc }}</option>
{% endfor %} </select><button type="submit" class="btn btn-success">Go</button>
<table class="table table-bordered table-striped">
<thead>
<tr>
{% for item in showlist.get_header %}
<th>{{ item }}</th>
{% endfor %} </tr> </thead>
<tbody>
{% for data in showlist.get_body %} <tr>
{% for item in data %}
<td>{{ item }}</td>
{% endfor %} </tr>
{% endfor %} </tbody>
</table>
<nav class="pull-right">
<ul class="pagination">
{{ showlist.pagination.page_html|safe }}
</ul>
</nav> </form>
</div> <div class="col-md-3">
<div class="filter">
<h4 style="">Filter</h4>
{% for filter_field,linktags in showlist.get_filter_linktags.items %}
<div class="well">
<p>By {{ filter_field.upper }}</p>
{% for link in linktags %}
<p>{{ link|safe }}</p>
{% endfor %}
</div>
{% endfor %} </div>
</div>
</div>
</div> <script> $("#choice").click(function () { if($(this).prop("checked")){
$(".choice_item").prop("checked",true)
}else {
$(".choice_item").prop("checked",false)
} }) </script>
</body>
</html>

贴上笔记

stark

   分页
分页组件
保存搜索条件 search action filter: print("filter_field",filter_field) # "publish"
filter_field_obj=self.config.model._meta.get_field(filter_field)
print("filter_field_obj",filter_field_obj)
print(type(filter_field_obj))
from django.db.models.fields.related import ForeignKey
from django.db.models.fields.related import ManyToManyField
print("rel...",filter_field_obj.rel.to.objects.all())
self.config.model._meta.get_field(filter_field) 通过字符串找到拿到该名字表的对象
只要属性里面有 (to=) 就可以用
filter_field_obj.rel.to 拿到关联表 class对象

10.19stark组件开发(三)的更多相关文章

  1. 基于GBT28181:SIP协议组件开发-----------第三篇SIP注册流程分析实现

    原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3941172.html,qq:1269122125. 上两章节简要的 ...

  2. ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇 第三章 为控件添加事件 后篇 前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是 ...

  3. ASP.NET自定义控件组件开发 第一章 第三篇

    原文:ASP.NET自定义控件组件开发 第一章 第三篇 第三篇:第一章的完结篇 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待 ...

  4. ASP.NET自定义控件组件开发 第一章 第三篇 第一章的完结篇

    ASP.NET自定义控件组件开发 第一章 第三篇   第三篇:第一章的完结篇 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ...

  5. 10 款提高开发效率的 jQuery/CSS3 组件

    前端开发是一项十分繁琐而又耗体力的工作,如何更有效率的开发我们的应用,很多人会选择适当地使用一些jQuery插件.今天就要给大家分享10款可以提高开发效率的jQuery/CSS3组件.部分插件可以下载 ...

  6. ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇

    原文:ASP.NET自定义控件组件开发 第三章 为控件添加事件 前篇 第三章 为控件添加事件 好了,我们之前以前开发一个控件.而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件. 系列 ...

  7. Vue (三) --- Vue 组件开发

    ------------------------------------------------------------------好心情,会让你峰回路转. 5. 组件化开发 5.1 组件[compo ...

  8. vue 开发系列(三) vue 组件开发

    概要 vue 的一个特点是进行组件开发,组件的优势是我们可以封装自己的控件,实现重用,比如我们在平台中封装了自己的附件控件,输入控件等. 组件的开发 在vue 中一个组件,就是一个独立的.vue 文件 ...

  9. 从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件

    标题:从零开始实现ASP.NET Core MVC的插件式开发(三) - 如何在运行时启用组件 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/112 ...

随机推荐

  1. shell自动补全功能:bash和zsh

    首要一点:shell有多种,比如bash.zsh.csh.ksh.sh.tcsh等 因此,制作自动补全功能时,要先搞清楚,你使用的是哪种shell,各个shell制作方法是不同的,网上大部分介绍的是关 ...

  2. JavaScript之Date日期对象扩展

    各种时间加减 收藏起来以备后用 //名称:日期加法函数 //参数:part(year.month.day.hour.minute.second.millisecond) //返回:Date对象 Dat ...

  3. grid - 网格轨道最小和最大尺寸

    可以通过minmax()函数来创建网格轨道的最小或最大尺寸. minmax()函数接受两个参数: 第一个参数定义网格轨道的最小值 第二个参数定义网格轨道的最大值 可以接受任何长度值,也接受auto值. ...

  4. PEM文件

    原文链接: http://blog.sina.com.cn/s/blog_489f88710100a59w.html OpenSSL 使用 PEM 文件格式存储证书和密钥.PEM 实质上是 Base6 ...

  5. SNF开发平台WinForm-Grid表格控件大全

    我们在开发系统时,会有很多种控件进行展示,甚至有一些为了方便的一些特殊需求. 那么下面就介绍一些我们在表格控件里常用的方便的控件:   1.Grid表格查询条 Grid表格下拉 3.Grid表格弹框选 ...

  6. Android Studio updating indices 一直刷新和闪烁

    Android Studio 更新到了 3.1.3 版本,在导入了工程以后,一直出现了 updating indices 刷新的情况,造成闪烁,在切换到其他视图以后,Android Studio 会一 ...

  7. 【Tomcat】面向初级 Web 开发人员的 Tomcat

    Apache Tomcat 应用服务器不再是高级 Web 系统开发人员的专用领域.在本教程中,Sing Li 将向初级 Web 开发人员展示如何利用他们当前的 Java™ 开发技能,使用 Tomcat ...

  8. 【Python】将python3.6软件的py文件打包成exe程序

    下载pyinstaller pyinstaller 改变图标 pyinstaller -F --icon=my.ico xxx.py 采用命令行操作的办法 在cmd命令行中,输入代码: 首先,前往Py ...

  9. [转] BootStrap table增加一列显示序号

    原文地址:https://blog.csdn.net/aboboo5200/article/details/78839208 最近由于项目需要,使用BootStrap table做数据展示,其中要在第 ...

  10. cordova打包vue2(webpack)android、ios app

    使用cordova打包vue2(webpack)app for android ios1.vue项目通过vue-cli脚手架建立项目,使用webpack进行打包,下边是一整套命令. #npm 版本最好 ...