Django是一个由Python写成的开放源代码的Web应用框架,它最初是被用来开发管理劳伦斯出版集团旗下的一些以新闻内容为主的网站,即CMS(内容管理系统)软件。 并于2005年7月在 BSD 许可证下发布。这套框架是以比利时的吉普赛爵士吉他手 Django Reinhardt 来命名的。因为 Django 的是在一个快节奏的新闻编辑室环境下开发的,它的目的是使常见的 Web 开发任务,快速和容易。css
Django官网:https://www.djangoproject.com/html
Django中文网:https://www.django.cnpython
Django的框架模式mysql
Django采用了MTV设计模式git
M | Models | 模型 |
---|---|---|
T | Templates | 模板 |
V | Views | 视图 |
Django是一个Web应用框架,他是如何处理请求和响应的正则表达式
URL ( urls.py )请求调度,当有缓存页面的时候直接返回内容。
视图函数( view.py )执行所请求的操做,一般包括读写数据库。
模型( models.py )定义了 Python 中的数据并与之交互。一般包含在一个关系数据库( MySQL、PostgreSQL SQLite 等),其余数据存储是可能的( XML、文本文件、LDAP、等)。
请求执行任务后,视图返回一个 HTTP 响应对象(一般是通过数据处理的一个模板)。可选的:视图能够保存一个版本的 HTTP 响应对象,返回携带一个时间戳,来告诉浏览器这个视图的更新时间。
模板一般返回 HTML 页面。Django 模板语言提供了 HTML 的语法及逻辑。算法
第一行和第三行均可以随便使用sql
网络很差用第三行数据库
pip install Django==2.1 #用国内的镜像网站,以下 pip install Django==2.1 -i https://pypi.douban.com/simple
import django print(django.get_version()) #结果: 2.1
python -m django --version #结果 2.1
django-admin startproject mysite
#若是咱们在项目外面,先要进入项目里 cd mysite #windows使用dir查看当前在哪里,若是有manage.py就表明咱们能够正确使用下面的命令 #建立应用程序 python manage.py startapp app01
python manage.py runserver #默认端口是8000 #使用上面的命令就能够了,下面不常常用 #改端口 python manage.py runserver 8080 #改访问地址和端口 python manage.py runserver 0.0.0.0:8080
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser user:输入:admin email:不写也行 password:输入:admin123 验证password:输入:admin123 让你确认:输入:y
注:自动从新加载 runserver,根据须要开发服务器自动从新加载Python代码为每一个请求。您不须要从新启动服务器代码更改生效。然而,像添加文件某些操做不触发从新启动,因此你必须从新启动在这些状况下的服务器。django
基本目录结构及做用:
mysite/ # 项目的容器,名字随便起
manage.py # 命令行实用工具,以各类方式与该Django项目进行交互
mysite/ # 实际的Python项目
init.py # 空文件,导入不出错
settings.py # 这个Django项目配置
urls.py # 这个Django项目的URL声明; 一个Django驱动网站的“目录”
wsgi.py # 一个入口点为WSGI兼容的Web服务器,以知足您的项目
Django自带数据库,咱们也能够选择不更改,项目开发中通常会更改使用的数据库,更改数据库配置在settings.py文件里
目前可使用mysql来代替pymysql了
pip install mysql
DATABASES = { 'default'{ 'ENGINE':'django.db.backends.mysql', 'NAME':'你的数据库名称', 'USER':'你的用户名', 'PASSWORD':'你的密码', 'HOST':'127.0.0.1', 'PORT':'3306', } }
也在settings里修改,主要放html文件
TEMPLATE_DIRS = ( os.path.join(BASE_DIR,'templates'), )
也在settings里修改,放css,js等文件
STATICFILES_DIRS = ( os.path.join(BASE_DIR,'static'), )
路由系统就像咱们咱们的书本的目录,书本的目录会告诉你那一页是什么,你翻到那一页就能看到相关的文字,路由系统就是,你对这个路由系统里的一个url地址发起了请求,路由系统会到对应的views函数去进行相关的处理,即这个url要用某个指定的views函数去处理。
来看下示例,django是怎么规定构造路由的
from app01 import views urlpatterns = [ path(r'^login$',views.LoginView), path(r'^register$',views.RegisterView), ]
from app1 import views urlpatterns = [ url(r'^manage1/(\d)', views.manage1), url(r'^manage2/(?P\w)/(?P\d)', views.manage2), url(r'^manage3/(?P\w)', views.manage3,{'id':333}),]
注意:
url多传一个参数,那views对应的函数就要多接收一个参数
要否则会报错的
若是映射url太多了,全写在一个urls.py文件里显得繁琐,因此出现了二级路由
就是项目的urls.py文件负责接收客户发过来请求它判断你传来的东西有没有它下面应用里的urls.py文件里有没有,若是有就告诉应用的的urls来接收,让它去处理,没有就给你报错
一级路由写法
项目的urls.py文件里
from django.urls import path, include urlpatterns = [ path(r'app01/',include('app1.urls')) ]
Django是如何处理一个请求的
当用户请求从您的 Django 的网站页面,这是该系统遵循以肯定哪些 Python 代码执行的算法: Django 请求是 URL 配置模块配置。一般经过值 ROOT_URLCONF 设置,但若是传入 HttpRequest 对象具备 urlconf 属性(由中间件设置),它的值将代替的可使用 ROOT_URLCONF 的设置。 Django 的负载是 Python 模块并寻找变量 urlpatterns。这是一个 django.conf.urls.url() 实例。 Django 的贯穿每一个 URL 模式,从而,在所请求的 URL 匹配的第一个中止。 一旦某个正则表达式相匹配,就运行相对应的视图函数(或基于类的视图)。该视图被传递如下参数: HttpRequest 对象。 若是匹配的正则表达式没有返回命名组,而后从正则表达式比赛是做为位置参数。 关键词参数是由由正则表达式匹配的任何命名组,由指定的可选参数的任何覆盖的 kwargs参数 django.conf.urls.url()。 若是没有正则表达式匹配,或者若是一个异常在这个过程当中的任何一点时提出,Django的调用适当的错误处理视图。
from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive), url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),]
注意事项:
要捕获从URL中的值,用 括号括起来,会当参数传入views视图
没有必要添加一个斜体,由于每一个URL都有。例如,它^articles不是^/articles.
在‘r’前面的每个正则表达式是可选的,建议,它告诉python字符串是原始的,没有字符要转义
请求/articles/2005/03/将匹配列表中的第三项,Django将调用该函数。
views.month_archive(request,‘2005’,‘03’)
/articles/2005/3/ 不会匹配任何 URL 模式,由于在列表中的第三项中须要两位数字的月份。
/articles/2003/ 将匹配的列表,而不是第二个第一图案,由于该图案,以便测试,第一个是在第一测
试经过。随意利用顺序插入特殊状况是这样的。在这里,Django的将调用该函数
views.special_case_2003(request)
/articles/2003 不匹配任何这些模式,由于每一个模式要求 URL 以斜线结束。
/articles/2003/03/03/ 将匹配的最终格局。Django 的将调用该函数。
views.article_detail(request,'2003', '03', '03')
上面的例子使用了简单的,非命名的正则表达式组(经过括号)来捕获URL的位,并经过他们的位置参数的视图,在更高级的用法,它可使用命名正则表达式组成来捕获URL位,将它们做为关键字参数传递给视图。
例子:
from django.conf.urls import url from .import views urlpatterns = [ url(r'^articles/2003/$',views.special_case_2003), url(r'^articles/(?P[0-9]{4})/$',views.year_archive), url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/$', views.month_archive), url(r'^articles/(?P[0-9]{4})/(?P[0-9]{2})/(?P[0-9]{2})/$',views.article_detail), ]
这正好完成一样的事情,前面的例子,一个细微的差异:捕获的值传递给查看功能做为关键字参数,而不是位置参数。例如:
请求/articles/2005/03/会调用函数来代替,views.month_archive(request, year='2005',month='03')views.month_archive(request, '2005', '03')
请求/articles/2003/03/03/会调用该函数,views.article_detail(request, year='2003',month='03', day='03')
在实践中,这意味着你的 URLconf 稍微更明确,不容易参数顺序错误 - 你能够在你的意见'函数定义从新排序的参数。固然,这些优势来在简短的费用; 一些开发任务命名组的语法丑陋,太冗长。
匹配/分组算法
这里的URL配置解析器遵循算法,相对于正则表达式命名组与非命名组:
若是有任何命名参数,它会使用这些,而忽略非命名参数。
不然,它会经过全部非命名参数做为位置参数。
在这两种状况下,被赋予按任何额外的关键字参数传递额外的选项来查看功能也将被传递给视图请求/articles/2005/03/会调用函数来代替,views.month_archive(request,year=‘2005’,month=‘03’)
3> What the URLconf searches against
The URLconf searches against the requested URL, as a normal Python string. This does not include GET or POST parameters, or the domain name.
For example, in a request to https://www.example.com/myapp/, the URLconf will look for myapp/.
In a request to https://www.example.com/myapp/?page=3, the URLconf will look for myapp/.
该URL配置不看请求方法。换言之,全部的请求的方法,GET,POST 等将被路由到为相同的URL,相同的功能。
4> 捕获的参数老是字符串
每一个捕获的参数发送到视图做为普通的 Python 字符串,不管什么样的匹配正则表达式匹配。
例如,在该URL配置行:
url(r'^articles/(?P[0-9]{4})/$', views.year_archive),
...的 year参数传递给 views.year_archive()将是一个字符串,
不是一个整数,即便 [0-9]{4} 将只匹配整数字符串。
5> 指定view的默认设置
一个方便的技巧是你的观点的论据指定默认参数。下面是一个例子的 RLconf 和见解:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^blogs/$',views.page), url(r'blog/page(?P[0-9]+)/$',views.page), ]
views.py
def page(request,num='1'): ''' 处理语句块 '''
对逻辑负责处理用户的请求并返回相应,返回能够是HTML内容的网页,或者重定向,或者错误,或者字典
每一个应用都有views.py文件
render() render(request,template_name,context=None,content_type=None,status=None,using=None)[source]
结合给定的模板与一个给定的上下文,返回一个字典HttpRespone在渲染文本对象
所需的参数
template_name 一个模板的使用或模板序列名称全称。若是序列是给定的,存在于第一个模板将被使用。
可选参数
context 一组字典的值添加到模板中,默认状况下这是一个孔子点
content_type MIME类型用于生成文档
status 为响应状态代码,默认值为200
using这个名字一个模板引擎将使用的模板
例子:
from django.shortcuts import render def my_view(request): return render(request,'myapp/index.html',{'fpp','bar',},content_type='application/xhyml+xml')
redirect()
redirect(to,permanent=False,*args,**kwargs)[source] 默认状况下,为临时重定向,经过permanent=True设置永久重定向
例子:
def my_view(request): ... return redirect('/some/url/') def my_view(request): ... obj = MyModel.opbjects.get(...) return redirect(object,permanent=True)
django使用请求和响应对象在系统间传递状态
当请求一个页面时,django建立一个HttpRequest对象包含原数据的请求,而后django加载适当的视图,经过HttpRequest做为视图函数的第一个参数,每一个视图负责返回一个HttpResponse目标
HttpRequest.scheme
一个字符串表示请求的计划方案(HTTP或者HTTPS)
一般HttpRequest.path
一个字符串的完整路径的请求
HTTPRequest.method
请求HTTP的方法,这里保证要大写
#伪代码 if request.method == 'GET': ''' 执行业务代码 返回结果 ''' return HttpResponse('结果')
#业务逻辑:若是请求来的是GET,你返回个GET字符串 #真代码 class GETView(objects): def getview(self,request): if request.method == 'GET': return HttpResponse('GET')
if request.method == 'GET': return HttpResponse('GET') elif request.method == 'POST': return HttpResponse('POST') elif request.method == 'PUT': return HttpResponse('PUT') elif request.method == 'DELETE': return HttpResponse('DELETE') else: return HttpResponse('来了老弟!')
字典包含全部给定的HTTP GET 参数对象
HttpRequest.GET
字典包含全部给定的HTTP POST 参数对象,提供请求包含表单数据
HttpRequest.POST
一个标准的python字典,包含全部的COOKIES,KEY和VALUES都是字符串
字典包含全部上传的文件
HttpRequest.FILES
语法:
HttpRequest.FILES filename #上传的文件名 content_type #上传文件的类型 content #上传文件的内容
HttpRequest.META
一个标准的Python字典包含全部可用的HTTP头,可用标题取决于客户端和服务器。如下是例子
CONTENT_LENGTH | 请求体的长度(一个字符串 |
---|---|
CONTENT_TYPE | 请求体的类型 |
HTTP_ACCEPT | 为响应–能够接受的内容类型 |
HTTP_ACCEPT_ENCODING | 接受编码的响应 |
HTTP_ACCEPT_LANGUAGE | 接受语言的反应 |
HTTP_HOST | 客户端发送的HTTP主机头 |
HTTP_REFERER | 参考页面 |
HTTP_USER_AGENT | 客户端的用户代理字符串 |
QUERY_STRING | 查询字符串,做为一个单一的(分析的)字符串 |
REMOTE_ADDR | 客户端的IP地址 |
REMOTE_HOST | 客户端的主机名 |
REMOTE_USER | 用户经过Web服务器的身份验证 |
REQUEST_METHOD | 字符串,如"GET"或"POST" |
SERVER_NAME | 服务器的主机名 |
SERVER_PORT | 服务器的端口(一个字符串) |
对于HttpRequest 对象来讲,是由django自动建立的,可是,HttpResponse 对象就必须咱们本身建立。每一个 view 请求处理方法必须返回一个 HttpResponse 对象。
HttpResponse 类在 django.http.HttpResponse
字符串使用:
典型的用法是经过页面的内容,为一个字符串
for django.http import HttpResponse response = HttpResponse("hello world") response = HttpResponse("hello world",content_type="text/plain")
若是你想添加内容的增量
response = HttpResponse() response.write("hello world") response.write("你好") #特性与方法: HttpResponse.content 一个bytestring表明内容HttpResponse.charset
一个字符串的字符集表示的响应将编码
HttpResponse.status_code
HTTP状态代码为响应码
HttpResponse.streaming
这个属性永远为假,通常用于中间件
HttpResponse.closed
方法:
先写的代码,后写的注释
HttpResponse.__init__(content='',content_type=None,status=200,reason=None,charset=None)[source] #实例化类自动执行的方法 HttpResponse.__setitem__(header,value) #为给定值给定的标题名称,都是字符串 HttpResponse.__delitem__(header) #删除标题的名称,不区分大小写 HttpResponse.__getitem__(header) #获取给定标题名称。不区分大小写。 HttpResponse.has_header(header) #检查是否具备给定名称的一个标题 HttpResponse.setdefault(header, value) #设置一个标题,除非它已经设置。 HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=False) #设置一个cookie。参数跟标准库的Cookie对象差很少 HttpResponse.set_signed_cookie(key, value, salt='', max_age=None, expires=None, path='/', domain=None, secure=None, httponly=True) #加密cookice,能够用 HttpRequest.get_signed_cookie() 获取,固然你也能够加盐 HttpResponse.delete_cookie(key, path='/', domain=None) #删除Cookie与给定键。 #HttpResponse子类: class HttpResponseRedirect[source]
构造函数的第一个参数是必需的路径redirectto,这是一个彻底合格的URL,一个合格的URL(https://www.baidu.com/搜索/),没有一个绝对的路径(例如:域搜索//),甚至是相对路径(如‘/’),
optionalconstructor参数。请注意,这将返回一个HTTP状态代码302。
class HttpResponsePermanentRedirect[source]
像httpresponseredirect,但它返回一个永久重定向(HTTP状态代码301)而不是“发现”的重定向(状态代码302)
class HttpResponseNotModified[source]
构造函数不带任何参数和NO含量应该被添加到这一反应。使用指定一个页面没有被modifiedsince用户的最后一个请求(状态代码304)。
class HttpResponseBadRequest[source]
就像HttpResponse但使用400状态码
class HttpResponseNotFound[source]
就像HttpResponse但使用404状态码
class HttpResponseForbidden[source]
就像HttpResponse但使用403状态码
class HttpResponseNotAllowed[source]
像HttpResponse,但使用405状态码。第一argumentto构造函数要求准许清单的方法(如(get,后])
class HttpResponseGone[source]
就像HttpResponse但使用410状态码
class HttpResponseServerError[source]
就像HttpResponse但使用500状态码
做为一个Web框架,Django须要模板,模板包含所需的HTML输出静态部分以及动态内容插入。 模板的执行 from datetime import datetime def current_datetime(request): now = datetime.datetime.now() html = "it is now %s" % now return HttpResponse(html) from django import template t = template.Templatge("my name is {{name}}") c = template.Context({"name":"老王"}) print(t.render(c)) import datetime from django import template import DjangoDemo.settings now = datetime.datetime.now() fp = open(settings.BASE_DIR+"/templates/home/index.html") t = template.Template(fp.read()) fp.close() html = t.render(template.Context({'current_date':now})) return HttpResponse(html) from django.template.loader import get_template from django.template import Context from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() t = get_template('current_datetime.html') html = t.render(Content({'current_date':now})) return HttpResponse(html) reurn render_to_response("Account/login.html",data,context_instance=RequestContext(request))
模板中也有本身的语言,该语言实现数据展现 {{item}} {% for item in item_list %} {{item}} {% endfor %} forloop.counter forloop.first forloop.last {% if ordered_warranty %} {% else %} {% endif %} 母板:{% block title %}{% endblock %} 子板: {% extends"base.html" %} 帮助方法: {{ item.event_start|date:"Y-m-d H:i:s"}} {{ bio|truncatewords:"30" }} {{ my_list|first|upper }} {{ name|lower }}
自定义simple_tag
在app中建立templatetags模块
建立任意名字的.py文件
!/usr/bin/env python coding:utf-8 from django import template from django.utils.safestring import makesafe from django.template.base import resolve_variable,Node,TemplateSyntaxError register = template.Libary() @register.simple_tag def my_simple_time(a1,a2,a3): return a1+a2+a3 @register.simple_tag def my_input(id,arg): result = " "%(id,arg) return mark_safe(result)
在使用自定义simple_tag的html文件中导入以前建立任意名字的.py文件
{% load xx %} //使用simple_tag {% my_simple_time 123 %}
在settings中配置当前app,否则django没法找到自定义的simple_tag
INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01', )
Django提供了一个抽象层(Model)的构建和管理Web应用程序的数据
每一个模型是一个python类,子类 django.db.models.model
模型中的每一个属性表明数据库中的一个字段。
例子:
from django.db import models class Person(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=30)
models.AutoField #自增=int(11),若是没有的化,默认会生成一个名称为id的列,若是要显示的自定义的一个自增列,必须将给列设置为主键,主键设置方式:primary_key=True models.CharField #字符串字符段,必须有max_length参数 models.BooleanField #布尔类型=tinyint(1),不能为空,Blank=True models.ComaSeparatedlntegerField #用逗号分隔的数字=varchar,继承CharField,因此必须max_length参数 models.DateField #日期类型 date,对于参数,auto_now=True则每次更新都会更新这个事件,auto_now_add则只是第一次建立添加,以后的更新再也不改变 models.DateTimeField #日期类型 datetime 同DateField参数同样 models.Decimal #十进制小数类型=decimal,必须制定整数位max_digits和小数位decimal_places models.EmailField #字符串类型(正则表达式邮箱)=varchar,对字符串进行正则表达式 models.FloatField #浮点类型=double models.IntegerField #整型 models.BigIntegerField #长整型 integer_field_ranges = { 'SmallIntegerField': (-32768, 32767), 'IntegerField': (-2147483648, 2147483647), 'BigIntegerField': (-9223372036854775808, 9223372036854775807), 'PositiveSmallIntegerField': (0, 32767), 'PositiveIntegerField': (0, 2147483647), } models.IPAddressField #字符串类型(ipv4正则表达式) models.GenericIPAddressField #字符串类型(ipv4和ivp6是可选的),参数protocol能够是:both、ipv、ipv6,验证时,会根据设置报错 models.NullBooleanField #容许为空的布尔类型 models.PositivenlntegerField #正integer models.PositiveSmallIntegerField #正smallinteger models.SlugField #减号、下划线、字母、数字 models.SmallInterField #数字,数据库中的字段有:tinyint、smallint、int、bigint models.TextField #字符串=longtext models.TimeField #时间 HH:MM[:ss[.uuuuuuu]] models.URLField #字符串,地址正则表达式 models.BinaryField #二进制 models.ImageField #图片 models.FilePathField #文件
null=True #数据库中字段是否能够为空 blank=True #django的Admin中添加数据是是否容许空值 primary_key=False #主键,对AutoField设置主键后,就会代替原来的自增id列 auto_now #自动建立,不管添加或修改,都是当前操做的时间 auto_now_add #自动建立爱你,永远是建立时的时间 choices #choices例子 GENDER_CHOICE = ( (u'M',u'Male'), (u'F',u'Female'), ) gender = models.CharField(max_length=2,choices=GENDER_CHOICE) max_length default #默认值 verbose_name #Admin中字段的显示名称 nameidb_column #数据库中的字段名称 unique=True #不容许重复 db_index=True #数据库索引 editable=True #在Admin里是否可编辑 error_messages=None #错误提示 auto_created=False #自动建立