django知识回顾
Posted karina梅梅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django知识回顾相关的知识,希望对你有一定的参考价值。
一、web框架
1、web框架本质
众所周知,对于所有的web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端
1、浏览器(socket客户端) 2、发送IP和端口:http://www.baidu.com:80/index/ 3、请求方式: GET:请求头: 如:http1.1 /index?p=123 请求体: 无内容 POSt:请求头 http1.1 /index?p=123 请求体 4、接收响应 普通响应:页面直接显示 重定向响应:再起一次Http请求 服务器(socket服务端) 1、启动并监听ip和端口,等待用户连接 接收请求进行处理,并返回 普通返回: 响应头: Access-Control-Allow-Origin:* Cache-Control:max-age=600 Date:Mon, 19 Jun 2017 00:57:43 GMT Expires:Mon, 19 Jun 2017 01:07:43 GMT Last-Modified:Wed, 24 May 2017 01:51:55 GMT Server:GitHub.com X-GitHub-Request-Id:C495:5EBC:8739EF:B817EE:59472187 响应体: <html> .... </html> 重定向返回: 响应头: LOCATION: \'http://www.baidu.com\' Access-Control-Allow-Origin:* Cache-Control:max-age=600 Date:Mon, 19 Jun 2017 00:57:43 GMT Expires:Mon, 19 Jun 2017 01:07:43 GMT Last-Modified:Wed, 24 May 2017 01:51:55 GMT Server:GitHub.com X-GitHub-Request-Id:C495:5EBC:8739EF:B817EE:59472187
WSGI(Web Sever Gateway Interface)是一种规范,它定义了使用python编写的web app与web server之间接口格式,
实现web app与web server间的解耦
2、自定义Web框架
通过python标准库提供的wsgiref模块开发一个自己的Web框架
from wsgiref.simple_server import make_server def index(): return \'index\' def login(): return \'login\' def routers(): urlpatterns = ( (\'/index/\',index), (\'/login/\',login), ) return urlpatterns def RunServer(environ, start_response): start_response(\'200 OK\', [(\'Content-Type\', \'text/html\')]) url = environ[\'PATH_INFO\'] urlpatterns = routers() func = None for item in urlpatterns: if item[0] == url: func = item[1] break if func: return func() else: return \'404 not found\' if __name__ == \'__main__\': httpd = make_server(\'\', 8000, RunServer) print "Serving HTTP on port 8000..." httpd.serve_forever()
HTML: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <h1>Index</h1> </body> </html> HTML: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <form> <input type="text" /> <input type="text" /> <input type="submit" /> </form> </body> </html>
对于上述代码,虽然可以返回给用户html的内容以实现复杂的页面,但是还是存在问题:如果给用户返回动态内容
自定义一套特殊的语法,进行替换
使用开源jinja2,遵循其指定语法
from wsgiref.simple_server import make_server from jinja2 import Template def index(): # return \'index\' # template = Template(\'Hello {{ name }}!\') # result = template.render(name=\'John Doe\') f = open(\'index.html\') result = f.read() template = Template(result) data = template.render(name=\'John Doe\', user_list=[\'alex\', \'eric\']) return data.encode(\'utf-8\') def login(): # return \'login\' f = open(\'login.html\') data = f.read() return data def routers(): urlpatterns = ( (\'/index/\', index), (\'/login/\', login), ) return urlpatterns def run_server(environ, start_response): start_response(\'200 OK\', [(\'Content-Type\', \'text/html\')]) url = environ[\'PATH_INFO\'] urlpatterns = routers() func = None for item in urlpatterns: if item[0] == url: func = item[1] break if func: return func() else: return \'404 not found\' if __name__ == \'__main__\': httpd = make_server(\'\', 8000, run_server) print "Serving HTTP on port 8000..." httpd.serve_forever()
HTML: <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <h1>{{name}}</h1> <ul> {% for item in user_list %} <li>{{item}}</li> {% endfor %} </ul> </body> </html>
遵循jinja2的语法规则,其内部会对指定的语法进行相应的替换,
从而达到动态的返回内容。
二、DjangoWeb框架
1、介绍Django
django:是一个由python写成的开放源代码的Web应用框架。
1、django #安装: pip3 install django 添加环境变量 创建project 命令:django-admin startproject mysite ---mysite ---settings.py ---url.py ---wsgi.py ---- manage.py(启动文件) 创建APP python mannage.py startapp app01 project - app01 - admin Django自带后台管理相关配置 - modal 写类,根据类创建数据库表 - test 单元测试 - views 业务处理 2、配置文件 a: 静态文件: 在settings里修改添加,放css,js,image等文件 创建static文件夹 STATIC_URL = \'/static/\' # 相当于别名 STATICFILES_DIRS = [ os.path.join(BASE_DIR,\'static\'), #切记一定加逗号 ] b:模板: 在settings里修改,放HTML文件 TEMPLATE_DIRS = ( os.path.join(BASE_DIR,\'templates\') ) c:数据库: # django支持sqlite,mysql, oracle,postgresql数据库 # django默认使用sqlite的数据库,默认自带sqlite的数据库驱动 , 引擎名称:django.db.backends.sqlite3 # 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替 # 设置放置的与project同名的配置的 __init__.py文件中 __init__.py 导入 import pymysql pymysql.install_as_MySQLdb() # 在settings 中修改DATABASES DATABASES = { \'default\': { \'ENGINE\': \'django.db.backends.mysql\', \'NAME\': \'dbname\', # 数据库名称 \'USER\': \'root\', # 用户名 \'PASSWORD\': \'xxx\', # 密码 \'HOST\': \'\', # IP,留空默认localhost \'PORT\': \'\', # 端口 } } d:新增app INSTALLED_APPS = [ \'django.contrib.admin\', \'django.contrib.auth\', \'django.contrib.contenttypes\', \'django.contrib.sessions\', \'django.contrib.messages\', \'django.contrib.staticfiles\', \'app01\', \'app02\', ] 3、路由关系 from app01 import views urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^index.html$\', views.index), ] 4、视图函数 def index(request): request.method request.GET request.POST return HttpResponse(\'字符串\') return redirect(\'URL\') return render(request,\'模板路径\',{}) # 1. 获取模板+数据,渲染 # 2. HttpReponse(...) 5、模板渲染 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>模板标记学习</h1> <p>{{ name }}</p> <p>{{ users.0 }}</p> //索引取值 <p>{{ users.1 }}</p> //索引取值 <p>{{ user_dict.k1 }}</p> <p>{{ user_dict.k2 }}</p>
例子:
urlpatterns = [ url(r\'^login/\', login), #后面配函数 url(r\'^index/\', index), ] def login(request): """ 处理用户请求,并返回内容 :param request: 用户请求相关的所有信息(对象) :return: """ #字符串 # return HttpResponse("这个世界很美好".encode("utf8")) #第一种返回字符串类型 #自动找到模板路径下的login.html文件,读取内容并返回给用户 #模板路径的配置 render if request.method=="GET": return render(request,\'login.html\') else: #用户POST提交的数据(请求体) u=request.POST.get("user") p=request.POST.get("pwd") if u=="root" and p=="123123": #登录成功 return redirect("http:www.oldboyde.com") #重定向 else: #登录失败 return render(request,"login.html",{\'msg\':\'用户名或密码错误\'}) # return render(request,\'login.html\') #参数是什么,就传什么参数,后面也可以加参数 login.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="/static/commons.css"> </head> <body> <h1>用户登录</h1> <form method="POST" action="/login/"> <input type="text" name="user" /> <input type="password" name="pwd" /> <input type="submit" value="登录" /> {{ msg }} </form> </body>
2、 Ajax:
jQuery其实就是一个javascript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能。
jQuery 不是生产者,而是大自然搬运工。
jQuery Ajax本质 XMLHttpRequest 或 ActiveXObject
jQuery.ajax(...) 部分参数: url:请求地址 type:请求方式,GET、POST(1.9.0之后用method) headers:请求头 data:要发送的数据 contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded; charset=UTF-8") async:是否异步 timeout:设置请求超时时间(毫秒) beforeSend:发送请求前执行的函数(全局) complete:完成之后执行的回调函数(全局) success:成功之后执行的回调函数(全局) error:失败之后执行的回调函数(全局) accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型 dataType:将服务器端返回的数据转换成指定类型 "xml": 将服务器端返回的内容转换成xml格式 "text": 将服务器端返回的内容转换成普通文本格式 "html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含JavaScript标签,则会尝试去执行。 "script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成普通文本格式 "json": 将服务器端返回的内容转换成相应的JavaScript对象 "jsonp": JSONP 格式 使用 JSONP 形式调用函数时,如 "myurl?callback=?" jQuery 将自动替换 ? 为正确的函数名,以执行回调函数 如果不指定,jQuery 将自动根据HTTP包MIME信息返回相应类型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .btn{ display: inline-block; padding: 5px 10px; background-color: coral; color: white; } </style> </head> <body> <h1>jQuery Ajax</h1> <h3>GET请求</h3> <div> <a class="btn" onclick="AjaxSubmit1();">点我</a> </div> <h3>POST请求</h3> <div> <a class="btn" onclick="AjaxSubmit3();">点我</a> </div> <script> function AjaxSubmit1() { $.ajax({ url: \'/ajax1.html\', type:\'GET\', data: {\'p\':123}, success:function (arg) { } }) }
1、 ajax参数 url: type: data: 1、value不能是字典 {k1:\'v1\',k2:[1,2,3,],k3; JSON.string} 2、$(\'\').serilizer() dataType:"JSON", # text,html,xml 单词太长了 traditional: success:function(arg) { #arg=>obj }, error:function(){ } 2、序列化 JavaScript: JSON.parse() JSon.stringify() Django: json.dumps() json.loads() 问题: serilize: model.TB.objects.all() json: model.TB.objects.value() json: model.TB.objects.value_list()
3、路由系统
URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表;
你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。
a:单一路由对应 url(r\'^index$\', views.index),
b:基于正则的路由 url(r\'^index/(\\d*)\', views.index), url(r\'^manage/(?P<name>\\w*)/(?P<id>\\d*)\', views.manage),
c:添加额外的参数 url(r\'^manage/(?P<name>\\w*)\', views.manage,{\'id\':333}),
d:为路由映射设置名称(反向生成url) url(r\'^home\', views.home, name=\'h1\'), url(r\'^index/(\\d*)\', views.index, name=\'h2\'), urls: url(r\'^index/(\\d+)/\',views.index,name="n1"), url(r\'^index/(?P<a1>\\d+)/\',views.index,name="n1"), views: from django.urls import reverse #根据名字反转成url def index(request,a1): #一一对应关系 user_list=[ "alex","eric","tony" ] v=reverse("n1",args=(1,)) #args= 数字自己规定 写的是1 url也会体现出来 and v=reverse("n1",kwargs={\'a1\':11111}) print(v) return render(request,\'index.html\',{"user_list":user_list}) 在html里写 url(r\'^login/\',views.login,name=\'m1\'), <form method="POST" action="{% url "m1" %}"> /* 根据名称也可以反生url*/ url(r\'^edit/(\\w+)/\', views.edit,name=\'n2\') <li>{{ i }}<a href="{% url \'n2\' i %}">| 编辑</a></li> 跳转的时候也可以做,不用写url
e:路由分发 如果映射url太多,全写一个在 urlpatterns 显得繁琐,so 路由分发应用而生 urls.py url(r\'^app01/\',include(\'app01.urls\')), 总路由: url(r\'^\',default), url不存在的话 可以默认写 or 跳转到index 的路径下 url(r\'^\',views.index), #路由默认不写 或者路由错误 直接执行index的函数 app01.urls.py url(r\'^index.html$\',views.index),
额外: 终止符:^edits$ 伪静态:url(r’^edit/(\\w+).html$’,views.edit),
4、视图函数(CBV & FBV)
CBV: # from django.views import View #导入一个 View 以便类继承 # class Login(View): #继承一个特殊的类 View # """ # 提交方法 # get 查 # post 创建 # put 更新 # delete 删除 # """ # # def get(self,request): #get请求取值 # return render(request,\'login.html\') # # def post(self,request): #post请求取值 # print(request.POST.get("user")) # return HttpResponse("Login.post") urlpatterns = [ url(r\'^admin/\', admin.site.urls), url(r\'^test.html$\',views.test), #url对应函数 url(r\'^login.html$\',views.Login.as_view()), #url对应类 ] <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form method="POST" action="/login.html"> <input type="text" name="user"/> <input type="submit" value="提交"/> </form> </body> </html>
5、ORM操作:
a.创建表 from django.db import models class User_type(models.Model): uid = models.BigAutoField(primary_key=True) title = models.CharField(max_length=32) class User_info(models.Model): name = models.CharField(max_length=32) age = models.CharField(max_length=32) ut = models.ForeignKey("User_type") python manage.py makemigrations python manage.py migrate
---------------------其它--------------------- class part(models.Model): cid = models.BigAutoField(primary_key=True) title = models.CharField(max_length=32,null=False) class student(models.Model): sid = models.BigAutoField(primary_key=True) name = models.CharField(max_length=32,null=False) pub_data=models.DateField() age = models.IntegerField(default=18) # 新增加的列 如果原先表里有值,写default ug = models.ForeignKey("part",null=True) #如果新增加外键,加null=True
b:ORM操作: 基本操作: #增 # models.User_type.objects.create(title="黑金用户") # obj = models.User_type(title="小白用户") # obj.save() #删 #models.User_type.objects.filter(title="小白用户").delete() # 删除指定条件的数据 #改 #models.User_type.objects.filter(title="黑金用户").update(title="黑卡用户") # 修改指定条件的数据 #查 # models.User_type.objects.get(title="大白用户") # 获取单条数据,不存在则报错(不建议) # models.User_type.objects.all() # 获取全部 # models.User_type.objects.filter(title="小白用户") # 获取指定条件的数据 # models.User_type.objects.exclude(title="黄金用户") # 排除指定条件的数据
Django--ORM基本操作 请看我的另一篇博客:http://www.cnblogs.com/niejinmei/p/7089719.html
c:多对多操作
方法一: 通过外键创建第三张表 class Boy(models.Model): name = models.CharField(max_length=32) class Girl(models.Model): nick = models.CharField(max_length=32) class Love(models.Model): b = models.ForeignKey("Boy") g = models.ForeignKey("Girl") class Meta: unique_together = [ ("b","g"), ] #表里插入数据 objs = [ models.Boy(name=\'方少伟\'), models.Boy(name=\'游勤斌\'), models.Boy(name=\'于浩\'), models.Boy(name=\'陈涛\'), ] models.Boy.objects.bulk_create(objs,4) result = [ models.Girl(nick=\'于浩姐姐\'), models.Girl(nick=\'景甜\'), models.Girl(nick=\'刘亦非\'), models.Girl(nick=\'苍老师\'), ] models.Girl.objects.bulk_create(result, 4) models.Love.objects.create(b_id=1,g_id=1) models.Love.objects.create(b_id=1,g_id=2) models.Love.objects.create(b_id=1,g_id=3) models.Love.objects.create(b_id=2,g_id=4) ################### 查找和我有关系的女孩 四种方式 ################ obj = models.Boy.objects.filter(name="方少伟").first() love_list = obj.love_set.all() for row in love_list: print(row.g.nick) love_list = models.Love.objects.filter(b__name="方少伟") for row in love_list: print(row.g.nick) #下面两个效果好 love_list = models.Love.objects.filter(b__name="方少伟").values("g__nick") for item in love_list: print(item["g__nick"]) love_list = models.Love.objects.filter(b__name="方少伟").select_related("g") for obj in love_list: print(obj.g.nick)
通过 ManyToManyField 创建第三张表 class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField("Girl") class Girl(models.Model): nick = models.CharField(max_length=32) obj = models.Boy.objects.filter(name="方少伟").first() # print(obj.id,obj.name) # obj.m.add(2) # obj.m.add(1,3) # obj.m.add(*[4,]) # obj.m.remove(2) # obj.m.remove(1,3) # obj.m.remove(*[4,]) # obj.m.set([1,4,]) # girl_list = obj.m.all() # girl_list = obj.m.filter(nick="苍老师") # obj.m.clear() obj = models.Girl.objects.filter(nick="苍老师").first() v = obj.boy_set.all()
方式三:通过 外键 和 ManyToManyField 创建 class Boy(models.Model): name = models.CharField(max_length=32) m = models.ManyToManyField("Girl",through="Love",through_fields=("b","g",)) class Girl(models.Model): nick = mod以上是关于django知识回顾的主要内容,如果未能解决你的问题,请参考以下文章
$Django 路飞之小知识回顾,Vue之样式element-ui,Vue绑定图片--mounted页面挂载--路由携带参数
如何在 Django Summernote 中显示编程片段的代码块?
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段
django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)(代码片段