一. url知识

还记得include分发么?里面的参数都可以有些什么?

urlconf_module本质是返回的是模块路径对象
def include(arg, namespace=None, app_name=None):
.......
return (urlconf_module, app_name, namespace)

1. 字符串格式?

url(r'^joker/', include('app01.urls')),

源码解释。

patterns = getattr(urlconf_module, 'urlpatterns', urlconf_module)

通过反射找到urlconf_moduls模块下的urlpatterns,如果没有urlpatterns会报错

2. 列表格式?

url(r'^joker/', include([
url('login1', login),
])),

源码解释。

if isinstance(arg, tuple):
.......
else:
# No namespace hint - use manually provided namespace
urlconf_module = arg

走else,也就是urlconf_moduls返回的就是这个列表

3 元祖?

url(r'^joker/', ([
url('app01/',([(url('login',login))],None,None)),
url('login2',login),
],None,None)),

源码解释。

return (urlconf_module, app_name, namespace)

include分发本质返回的就是,url模块,app名字,命名空间,那我们直接把这个元祖写这里,相当于分发

最后,上面都是前面与后面的拼接成url

2. 装饰器

我们给视图函数(增删改查)加上了装饰器,其目的是让每个url都是个request对象,为了携带当前访问时候的数据

当时的代码如下

self.request = None 类属性当时为None
# 携带数据装饰器
def warp(self, view_func):
def inner(request, *args, **kwargs):
self.request = request ###### 每个增删改查在点击的时候都携带REQUEST这个数据
return view_func(request, *args, **kwargs)
return inner # LIST_VIEW = WARP(LIST_VIEW) == INNER (LIST_VIEW) ==
# URL
def get_urls(self): # 默认的增删改查 # 我这里获取的URL是不是应该加入别名?反向解析呢?
# url( 正则,视图(元祖,列表),命名空间)
app_model_name = (self.model._meta.app_label, self.model._meta.model_name) # 应用名称,表名称
temp = [
url("^$", self.warp(self.list_view), name="%s_%s_list" % app_model_name),
url("^add/$", self.warp(self.add_view), name="%s_%s_add" % app_model_name),
url("^(\d+)/edit/$", self.warp(self.edit_view), name="%s_%s_edit" % app_model_name), ### 注意小括号
url("^(\d+)/delete/$", self.warp(self.delete_view), name="%s_%s_delete" % app_model_name),
] return temp

stark用装饰器源码

装饰器学习

http://www.cnblogs.com/jokerbj/p/7247901.html

3. model取值操作

常规取值操作

http://www.cnblogs.com/jokerbj/p/8145387.html

针对表对象可以取一些特定的值,比如咱们的代码

# 注册,这是在启动的时候就会加载的
joker.site.register(models.Book)
# 针对model取值
model_name = model._meta.model_name # 数据库表名
app_label = model._meta.app_label # 应用表名
# 取表字段
verbox_name=self.model._meta.get_field('title').verbose_name # 如果 model里面没有指定verbose_name就是字段名,指定就是verbose_name对应的值
_field.rel.to.objects.all() # _field 是字段,拿到的是该字段的所有值

针对Q查询,看下咱们代码

condition = Q()    # 利用Q 查询
condition.connector = 'or' # 指定Q查询之间是什么关系
if key_word and self.show_search_form: # 有默认搜索值,并且前端开启页面
for field_name in search_fields: # 'title__contains','price',
condition.children.append((field_name,‘joker’)) # title=joker的值或者price=joker的值
print(condition) 数据查询这块就是
queryset = self.model.objects.filter(self.get_search_condition()) # 过滤条件

4. request.GET.urlencode()  携带数据跳转

我们之前为了保持每次搜索携带数据,引入了request.get.urleode方法,这个方法可以使请求的数据直接变成字符串

# 例如访问的url
http://127.0.0.1:8000/?page=1&id=2
# 如果我们用将这次请求利用request.GET.urlencode()打印
得到 page=&id= 的字符串
# 我们携带这个数据进入要编辑页面,当我们编辑完我们还会携带这个数据,返回之前我们页面,所以说这个数据就是当前页面的状态

有个问题?

如果请求携带的数据有重复怎么办?

我们引入QueryDict这个字典,因为普通的字典无法被urlencode,打开request.GET修改?

# queryset dict
from django.http import QueryDict # 获取当前请求头
query_str = self.request.GET.urlencode() # 请求数据 # QueryDict 字典加入值
parames = QueryDict(mutable=True) # 允许更改request.GET mutable 可变的意思
parames[self._query_param_key] = query_str # 加入当前URL数据 # 好了之后,反问哪个就加入下面经过urlencode处理的数据
return mark_safe("<a href='%s?%s'>edit</a>" % (a,b,parames.urlencode())) # 调用反向解析出来的url,就是这样携带数据访问 # 后端处理数据后,返回的页面就是携带之前的数据
list_query_str = request.GET.get(self._query_param_key)
list_url = "%s?%s" % (self.get_list_url(), list_query_str,)
return redirect(list_url)

强插一个知识点》》

config.request.GET.get(config.search_key,'')

如果没有获取不到该值,可以给个默认值空。当然也可以为别的,默认是None

强插一个知识点》》

_params.setlist(self.option.field_name,id_list) # 重新设置请求
url = '{0}?{1}'.format(self.request.path_info, _params.urlencode())

可以传入列表,元祖,重新赋值

5. button可以提交数据?

有时html页面button点击会出现自动提交表单的情况。

<form action="" method="post">
{% csrf_token %}
<input type="text" placeholder="xxx">
<button></button>
</form>

form表单下的按钮在没有指定type类型的时候,button会有一个默认的type=”submit”

给button设置一个类型type="button",这样button的类型就不是默认的submit了,就不会自动提交表单了

<form action="" method="post">
{% csrf_token %}
<input type="text" placeholder="xxx">
<button type="button"></button>
</form>

6. 模版语言里面不能用_  or __ 去调用

{{ cls._pk }}
{{ cls.__pk }}

7. 判断字段是不是外键,或者多对多关系

from django.db.models import ForeignKey,ManyToManyField
if isinstance(_field,ForeignKey):
pass

8. 取choices字段中文


device_status_choices = (
(1, '上架'),
(2, '在线'),
(3, '离线'),
(4, '下架'),
)
device_status_id = models.IntegerField(choices=device_status_choices, default=1)
return obj.get_gender_display() 
# 这里用法就是 get_fieldname_display() fieldname device_status_di中间加入字段就会自动拿到CHOICE对应的中文拿到前提就是这个对象有这个字段
# 前端 <td>{{ data.asset.get_device_status_id_display }}</td> 这样获取

9 . 单例模式

class Foo(object):
_instance = None def __init__(self, name):
self.name = name @classmethod
def instance(cls, *args, **kwargs):
if not Foo._instance:
obj = Foo(*args, **kwargs)
Foo._instance = obj
return Foo._instance obj1 = Foo.instance('alex')
obj2 = Foo.instance('alex')
print(id(obj1), id(obj2))

10. 反射

###  settings
# DB_PATH = "db.mysql.MySQLHelper"
DB_PATH = "db.sqlserver.SqlServerHelper" ### db 下的mysql/sqlserverPY文件
class MySQLHelper(object):
def fetchone(self):
"""
链接MySQL,获取一条数据
:return:
"""
print('MySQL.fetchone')
### app.py
from settings import DB_PATH # 我导入一段字符串
def func():
# 导入文件
# 反射
# DB_PATH = "db.mysql.MySQLHelper"
module_path, cls_name = DB_PATH.rsplit('.', maxsplit=) # db.mysql / db.sqlserver # 以字符串的形式导入模块
# from db import mysql 类似于 这种
import importlib 导入模块
module_obj = importlib.import_module(module_path) # # 去模块中导入类
cls = getattr(module_obj, cls_name) cls_name 是模块下的类 # 类实例化
obj = cls()
obj.fetchone() if __name__ == '__main__':
func()

11. 对象封装数据

class Foo(object):
def __init__(self, name, data_list):
self.name = name
self.data_list = data_list def __iter__(self):
yield "<div>"
yield "全部"
for item in self.data_list:
yield item
yield "</div>" obj_list = [Foo('富贵', ['男', '女']), Foo('强哥', ['已报名', '未报名']), Foo('熊平', ['内部转介绍', '百度推广'])] # 需求:循环对象时,先打印对象name属性,然后再答应123。
for obj in obj_list:
for item in obj:
print(item)

12. 弹出popup

三种window对象,弹出关闭
window.alert(123); 关闭
window.confirm(""); 交互 取消 关闭
window.prompt(""); 输入内容 取消 关闭
#############################   url代码
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^index/', views.index),
url(r'^pop/', views.pop),
] ############################ views代码
def index(request):
return render(request, 'index.html') def pop(request):
if request.method == "GET":
return render(request, 'pop.html')
else:
user = request.POST.get('user')
return render(request, 'pop_response.html', {'user': user}) ############################ index.html代码
<h1 id="i1">我会被更改的</h1>
<a href="#" onclick="popUp('http://www.oldboyedu.com')">点我点我</a> <script>
function xxxpopupCallback(text) {
document.getElementById('i1').innerHTML = text;
} function popUp(url) {
window.open('/pop/', "n1", "status=1, height:500, width:600, toolbar=0, resizeable=0");
} </script> ########################### pop.html代码
<form method="post">
{% csrf_token %}
<input type="text" name="user">
<input type="submit" value="保存">
</form> ########################### pop_response代码
<h1>正在关闭</h1>
<script>
(function () {
// 可以调用popup原页面的一个函数
opener.xxxpopupCallback("{{ user }}");
window.close();
})()
</script>

流程解释:

  我们访问到index页面,利用事件让浏览器弹出一个我们自定义的窗口(window.open),在这个窗口中我们给予他需要弹出的页面pop.html页面,并设置xxxpopupCallback接收到时候儿html的返回值。提交表单post发回视图,视图转给pop_response页面,匿名函数返回给源html值,opener.xxxpopupCallback("{{ user }}");随后关闭。

13. form表单补充

数据实时更新

方式一
class RegForm(forms.Form):
user = forms.CharField(max_length=32)
#gender_tuple=(0,'上海'),(1,'北京'),(2,'保定')
gender = forms.ChoiceField(choices =City.objects.all().values_list("id","name")) # 第一次启动时候数据拿了一遍,无法实时更新,如果数据更新了,页面显示不出来 def __init__(self,*args,**kwargs):
super(RegForm,self).__init__(*args,**kwargs) # 通过构造方法实时更新
#print("Ok")
print(self.fields["gender"].choices)
self.fields["gender"].choices=City.objects.all().values_list("id","name") 方式二 依赖 MODEL
from django.forms import ModelChoiceField,MultipleChoiceField class RegForm(forms):
gender = fields.ModelChoiceField(queyset=City.objects.all()) # 字段 页面单选 class RegForm(forms):
gender = fidles.MultipleChoiceField(queyset=City.objects.all()) # 字段 页面多选 # 方式三
class RegForm(ModelForm): # 依赖MODEL,同方式二,
class Meta:
model = UserInfor # 如果UserInfor是F,就生成ModelChoiceField,是M2,就生成MultipleChoiceField
fields = "__all__"

modelform转变form

class RegForm(ModelForm):    # 依赖MODEL,同方式二,
class Meta:
model = UserInfor # 如果UserInfor是F,就生成ModelChoiceField,是M2,就生成MultipleChoiceField
fields = "__all__"

读取model = userinfo中的字段,转变成form字段

class UserInfor(models.Model):
user=models.CharField(max_length=32)
gender=models.IntegerField(choices=((1,"男"),(2,"女")))
city=models.ForeignKey("City",default=1)
roles=models.ManyToManyField("Roles",default=1)
||||| class UserInfor(forms.Form):
user=forms.CharField()
gender=forms.TypedChoiceField(choices=((1,"男"),(2,"女")))
city=forms.ModelChoiceField(choices=City.objects.all())
roles=forms.ModelMultipleChoiceField(choices=Roles.objects.all())

循环form

def reg(reqeust):
form = RegForm() # form包含了表内的所有字段
for i in form:
print(i) <input type="text" name="user" required id="id_user" maxlength="" /> 因为内部的str方法才显示的标签,不过还是个对象,这个是前端渲染框的
     print(i.field) # <django.forms.fields.CharField object at 0x1068d1c88> boundield 里面的field字段打印就是每个字段的类型
    print(type(i)) <class 'django.forms.boundfield.BoundField'>,每个字段都是对象,被boundfield封装

前端页面 {{ field.label }},打印的是字段名称,如果有verbose_name打印这个,没有打印字段名字

源form学习

http://www.cnblogs.com/jokerbj/p/8157669.html

关于模拟admin实现stark组件的知识点的更多相关文章

  1. 模拟Django的admin自定义stark组件

    1.新建Django项目--新建app:app01和stark--在settings中配置app和数据库--在models.py中新建模型表--完成数据库迁移 2.在stark下的apps.py中: ...

  2. 10.15仿admin开发stark组件(一)

    2018-10-15 12:28:50 越努力,越幸运!永远不要高估自己! 低调做人,高调做事! 明天开stark项目!! admin 参考连接: http://www.cnblogs.com/yua ...

  3. admin源码解析以及仿照admin设计stark组件

    ---恢复内容开始--- admin源码解析 一 启动:每个APP下的apps.py文件中. 首先执行每个APP下的admin.py 文件. def autodiscover(): autodisco ...

  4. stark组件之pop操作【模仿Django的admin】

    一.先看下什么django的admin的pop到底是个什么东西 其实就是这么一个东西, a.在添加页面,在一对多和多对多的项后加了一个+号 b.点击这个加号,会弹出对应的添加 页面,在新的添加 c.添 ...

  5. 仿照admin的stark自定义组件的功能实现

    仿照admin的stark自定义组件的功能实现:其中最主要的就是增删改查的实现 1.查:首先页面中显示表头和数据,都是动态的,而不是写死的. (1) 先看表头和表单数据:这个是查看的视图函数,但是为了 ...

  6. stark组件之批量操作【模仿Django的admin】

    一.先看下django的admin是如何实现批量操作 首先在配置类中定义一个函数 然后我们为这个函数对象设置一个属性,这个属性主要用来显示在select标签中显示的文本内容 最后把函数对象放到一个ac ...

  7. stark组件之搜索【模仿Django的admin】

    一.先看下django的admin是如何做搜索功能的 配置一个search_fields的列表就可以实现搜索的功能 class testbook(admin.ModelAdmin): # 第一步,定义 ...

  8. stark组件之路由分发【模仿Django的admin】

    一.先看下django的admin是如何进行路由分发的 1.先看下django的admin的url路径有哪些 其实很简单,假如有一个书籍表,那么每张表对应四个url,增.删.改.查 查看的url ht ...

  9. stark组件之注册【模仿Django的admin】

    一.先看下django的admin是如何实现注册功能 首先导入admin这个对象和我们的model模块 from django.contrib import admin # Register your ...

随机推荐

  1. New Concept English there (2)Typing speed exercise

    typing speed (11words/ seconds) our vicar ia always rising money for one cause or another, but he ha ...

  2. 转:JAVA CAS原理深度分析

    看了一堆文章,终于把Java CAS的原理深入分析清楚了. 感谢GOOGLE强大的搜索,借此挖苦下百度,依靠百度什么都学习不到! 参考文档: http://www.blogjava.net/xylz/ ...

  3. c# DataTable 导出csv文件

    using System; using System.Data; using System.Configuration; using System.Collections.Generic; using ...

  4. losetup命令

    Linux losetup命令用于设置循环设备. 循环设备可把文件虚拟成区块设备,籍以模拟整个文件系统,让用户得以将其视为硬盘驱动器,光驱或软驱等设备,并挂入当作目录来使用. 语法 losetup [ ...

  5. flowable ProcessEngine和ProcessEngineConfiguration

    ProcessEngine是流程引擎,ProcessEngineConfiguration与前面四个引擎配置有些不同. ProcessEngineConfiguration增加了邮件服务和httpCl ...

  6. Unity内存存储揭秘

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...

  7. Ubuntu循环登录libGL error: fbConfigs swrast等

    Ubuntu16.04更新NVIDIA驱动后,无法进入桌面,使用vim .xsession-errors 查看错误信息,如下: libGL error: No matching fbConfigs o ...

  8. JMter请求参数中文显示乱码

    如上图所示,上传的参数为中文的时候,显示不出来,解决方法如下: 1.进入Jmter安装文件bin文件夹,找到文件jmeter.properties 2.在该文件找到jsyntaxtextarea.fo ...

  9. [Python] 比较两个数组的元素的异同

    通过set()获取两个数组的交/并/差集: print set(a) & set(b) # 交集, 等价于set(a).intersection(set(b)) print set(a) | ...

  10. kd树 求k近邻 python 代码

      之前两篇随笔介绍了kd树的原理,并用python实现了kd树的构建和搜索,具体可以参考 kd树的原理 python kd树 搜索 代码 kd树常与knn算法联系在一起,knn算法通常要搜索k近邻, ...