第1章 web框架的本质
1.1 socket
1.2 空格后面是主体内容
1.3 HTTP协议
1.3.1 响应流程
1.4 HTTP请求方法
1.5 HTTP工做原理
1.6 URL
1.7 HTTP请求格式
1.8 HTTP响应格式
1.9 根据不一样的路径返回不一样内容
1.10 进阶版
1.11 根据访问的路径返回不一样的动态页面
第2章 Django安装建立
2.1 部署安装
2.1.1 下载
2.2 命令行建立项目
2.2.1 djangoadmin
2.2.2 添加环境变量
2.2.3 建立命令
2.3 pycharm 形式建立项目
2.4 命令行启动项目
2.4.1 关闭
2.5 建立app
2.5.1 目录结构
2.6 注册APP
2.7 第一个index
第3章 函数规范
3.1.1 app.views.py:
3.1.2 untitled3.urls.py
3.1.3 disable cache
3.2 静态文件
3.2.1 别名
第4章 模板(未完待续)
4.1 建立templates目录
4.2 修改settings文件
4.3 render模块
4.4 特殊符号{{}}
4.4.1 变量
第5章 路由系统(未完待续)
5.1 基本格式
5.2 urls.py
5.3 参数说明
5.4 区别django2.0
5.5 注意事项
5.6 补充说明
第6章 settings介绍(未完待续)
6.1 目录介绍
6.2 模板配置
6.3 静态文件配置
6.4 中间件配置
第7章 Django视图函数
7.1 基础必备三件套:
7.2 HttpResponse
7.3 render
7.4 redirect
7.5 request
7.5.1 path_info
7.6 request.method
7.6.1 request.POST.get
7.6.2 request.GET
第8章 ORM数据库连接
8.1 建立数据库
8.2 配置settings
8.3 配置pymysql
8.4 配置models.py
8.5 执行数据库迁移的命令
8.6 ORM操做
8.6.1 查询
8.6.2 增长
8.6.3 删除
8.6.4 修改css
基于最基本的socket演变而来html
python_socket(代码)python
#!/usr/bin/env pythonmysql
# -*- coding:utf-8 -*-web
import socket正则表达式
sk = socket.socket()sql
sk.bind(('127.0.0.1',80))数据库
sk.listen()django
while True:bootstrap
conn,addr = sk.accept()
data = conn.recv(8096)
print(data)
conn.send(b"ok")
conn.close()
浏览器访问打印
b'GET / HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, sdch, br\r\nAccept-Language: zh-CN,zh;q=0.8\r\n\r\n'
b'GET /favicon.ico HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: keep-alive\r\nPragma: no-cache\r\nCache-Control: no-cache\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\r\nAccept: image/webp,image/*,*/*;q=0.8\r\nReferer: http://127.0.0.1/\r\nAccept-Encoding: gzip, deflate, sdch, br\r\nAccept-Language: zh-CN,zh;q=0.8\r\n\r\n'
咱们将\r\n替换成换行看得更清晰点:
GET / HTTP/1.1
Host: 127.0.0.1:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3355.4 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: csrftoken=CtHePYARJOKNx5oNVwxIteOJXpNyJ29L4bW4506YoVqFaIFFaHm0EWDZqKmw6Jm8
访问知乎显示
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',80))
sk.listen()
while True:
conn,addr = sk.accept()
data = conn.recv(8096)
print(data)
conn.send(b'HTTP/1.1 200 ok\r\nContent-Type: text/html: charset=utf-8\r\n\r\n')
conn.send('随便'.encode('utf-8'))
conn.close()
sk.close()
浏览器输出
1.3 HTTP协议
在浏览器地址栏键入URL,按下回车以后会经历如下流程:
l 浏览器向 DNS 服务器请求解析该 URL 中的域名所对应的 IP 地址;
l 解析出 IP 地址后,根据该 IP 地址和默认端口 80,和服务器创建TCP链接;
l 浏览器发出读取文件(URL 中域名后面部分对应的文件)的HTTP 请求,该请求报文做为 TCP 三次握手的第三个报文的数据发送给服务器;
l 服务器对浏览器请求做出响应,并把对应的 html 文本发送给浏览器;
l 释放 TCP链接;
l 浏览器将该 html 文本并显示内容;
共有八种方法(也称“动做”)来以不一样方式操做指定的资源,其中最多见的有两种:
l GET
向指定的资源发出“显示”请求,使用GET方法应该只用在读取数据,而不该该被用于产生反作用的操做中,例如在web application中,其中一个缘由是GET可能会被网络蜘蛛随意访问。
l POST
向指定资源提交数据,请求服务器进行处理(例如提交表单或者上环文件)。数据被包含在请求文本中,这个请求可能会建立新的资源或者修改现有资源,或者都有
HTTP协议定义Web客户端如何从Web服务器请求Web页面,以及服务器如何把Web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,请求报文包含请求的方法、URL、协议版本、请求头部和请求数据。服务器以一个状态行做为响应,响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
超文本传输协议(HTTP)的统一资源定位符将从因特网获取信息的五个基本元素包括在一个简单的地址中:
l 传送协议。
l 层级URL标记符号(为[//],固定不变)
l 访问资源须要的凭证信息(可省略)
l 服务器。(一般为域名,有时为IP地址)
l 端口号。(以数字方式表示,若为HTTP的默认值“:80”可省略)
l 路径。(以“/”字符区别路径中的每个目录名称)
l 查询。(GET模式的窗体参数,以“?”字符为起点,每一个参数以“&”隔开,再以“=”分开参数名称与数据,一般以UTF8的URL编码,避开字符冲突的问题)
l 片断。以“#”字符为起点
以http://www.luffycity.com:80/news/index.html?id=250&page=1 为例, 其中:
http,是协议;
www.luffycity.com,是服务器;
80,是服务器上的网络端口号;
/news/index.html,是路径;
?id=250&page=1,是查询。
大多数网页浏览器不要求用户输入网页中“http://”的部分,由于绝大多数网页内容是超文本传输协议文件。一样,“80”是超文本传输协议文件的经常使用端口号,所以通常也没必要写明。通常来讲用户只要键入统一资源定位符的一部分(www.luffycity.com:80/news/index.html?id=250&page=1)就能够了。
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',80))
sk.listen()
while True:
conn,addr = sk.accept()
data = conn.recv(8096)
print(data)
conn.send(b'HTTP/1.1 200 ok\r\nContent-Type: text/html: charset=utf-8\r\n\r\n')
url = data.decode('utf-8').split()[1]
print(url)
if url == '/oumei':
conn.send('欧美'.encode('utf-8'))
elif url == '/rihan':
conn.send('日韩'.encode('utf-8'))
else:
conn.send('正在录制中'.encode('utf-8'))
conn.close()
sk.close()
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
def oumei(url):
return '欧美{}'.format(url).encode('utf-8')
def rihan(url):
return '日韩{}'.format(url).encode('utf-8')
def guochan(url):
return '国产{}'.format(url).encode('utf-8')
list = [
('/rihan',rihan),
('/oumei',oumei),
('/guochan',guochan),
]
sk = socket.socket()
sk.bind(('127.0.0.1',80))
sk.listen()
while True:
conn,addr = sk.accept()
data = conn.recv(8096)
print(data)
conn.send(b'HTTP/1.1 200 ok\r\nContent-Type: text/html: charset=utf-8\r\n\r\n')
url = data.decode('utf-8').split()[1]
print(url)
func = None
for i in list:
if i[0] == url:
func = i[1]
break
if func:
ret = func(url)
else:
ret = '正在录制中'.encode('utf-8')
conn.send(ret)
conn.close()
sk.close()
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import socket
def index(url):
import time
with open('index.html','r',encoding='utf-8') as f:
data = f.read()
data = data.replace(@@xx@@,time.strftime("%Y-%m-%d %H:%M:%S"))
return data.encode('utf-8')
def oumei(url):
return '欧美{}'.format(url).encode('utf-8')
def rihan(url):
return '日韩{}'.format(url).encode('utf-8')
def guochan(url):
return '国产{}'.format(url).encode('utf-8')
list = [
('/rihan',rihan),
('/oumei',oumei),
('/guochan',guochan),
]
sk = socket.socket()
sk.bind(('127.0.0.1',80))
sk.listen()
while True:
conn,addr = sk.accept()
data = conn.recv(8096)
print(data)
conn.send(b'HTTP/1.1 200 ok\r\nContent-Type: text/html: charset=utf-8\r\n\r\n')
url = data.decode('utf-8').split()[1]
print(url)
func = None
for i in list:
if i[0] == url:
func = i[1]
break
if func:
ret = func(url)
else:
ret = '正在录制中'.encode('utf-8')
conn.send(ret)
conn.close()
sk.close()
index.html(代码)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>澳门首家皇家赌场上线啦!!</h1>
@@xx@@
</body>
</html>
版本信息:1.11 目前只有1.11支持python2.7
\
命令行:
命令行:pip3 install django==1.11.15
查看命令:pip3 list
pycham下载
django-admin startproject 项目名
例:
django-admin startproject s22
当前路径下建立的s22项目
cd C:\Users\Administrator\s22
python3 manage.py runserver
浏览器访问:
http://127.0.0.1:8000/
更改端口
python3 manage.py runserver 80
python3 manage.py runserver 127.0.0.1:9999
l 命令行建立
python manage.py startapp app01
l pycharm建立
admin -----管理后台
apps ----配置相关
models-----
views-------具体业务逻辑函数
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01',
'app02.apps.AppConfig' è 标准写法会自动读取app02下的py文件
]
urls.py:
from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse
def index(request):
return HttpResponse('这是index页面')
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'index',index)
]
输出
l urls.py---------------------只记录地址url
l app下的views.py-------写入函数代码
from django.shortcuts import render
# Create your views here.
from django.shortcuts import HttpResponse
def index(request):
return HttpResponse('<h1>这是index页面<\h1>')
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'index',views.index)
]
解释:清除缓存影响
settings.py
STATIC_URL = '/static999/' #别名
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static')
]
注释;变量名不能错有两个s
例:login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登陆页面</title>
<link rel="stylesheet" href="/static999/bootstrap-3.3.7/css/bootstrap.css">
<link rel="stylesheet" href="/static/lgoin.css">
</head>
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
templates.index:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>这是index页面!!!!!</h1>
</body>
</html>
app.vivews
# Create your views here.
from django.shortcuts import HttpResponse,render
def index(request):
# return HttpResponse('<h1>这是index页面<\h1>')
return render(request,'index.html')
{{}} 表示变量,在模板渲染的时候替换成值
{% %}表示逻辑相关的操做
{%endfor%}
{{ 变量名 }}
变量名由字母数字和下划线组成。
点(.)在模板语言中有特殊的含义,用来获取对象的相应属性值。
URL配置(URLconf)就像Django所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。
from django.conf.urls import url
urlpatterns = [
url(正则表达式, views视图,参数,别名),
]
从上往下进行匹配第一个参数是正则
示例
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'index',views.index)
]
示例:
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),
]
l 正则表达式:一个正则表达式字符串
l views视图:一个可调用对象,一般为一个视图函数
l 参数:可选的要传递给视图函数的默认参数(字典形式)
l 别名:一个可选的name参数
from django.urls import path,re_path
urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles/<int:year>/', views.year_archive),
path('articles/<int:year>/<int:month>/', views.month_archive),
path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail),
]
l urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则再也不继续。
l 若要从URL中捕获一个值,只须要在它周围放置一对圆括号(分组匹配)。
l 不须要添加一个前导的反斜杠,由于每一个URL 都有。例如,应该是^articles 而不是 ^/articles。
l 每一个正则表达式前面的'r' 是可选的可是建议加上。
是否开启URL访问地址后面不为/跳转至带有/的路径的配置项
APPEND_SLASH=True
Django settings.py配置文件中默认没有 APPEND_SLASH 这个参数,但 Django 默认这个参数为 APPEND_SLASH = True。 其做用就是自动在网址结尾加'/'。
其效果就是:
咱们定义了urls.py:
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^blog/$', views.blog),
]
访问 http://www.example.com/blog 时,默认将网址自动转换为 http://www.example/com/blog/ 。
若是在settings.py中设置了 APPEND_SLASH=False,此时咱们再请求 http://www.example.com/blog 时就会提示找不到页面。
mysite/
├── manage.py # 管理文件
└── mysite # 项目目录
├── __init__.py
├── settings.py # 配置
├── urls.py # 路由 --> URL和函数的对应关系
└── wsgi.py # runserver命令就使用wsgiref模块作简单的web server
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, "template")], # template文件夹位置
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
STATIC_URL = '/static/' # HTML中使用的静态文件夹前缀
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"), # 静态文件存放位置
]
说明:刚开始学习时可在配置文件中暂时禁用csrf中间件,方便表单提交测试。
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
1. HttpResponse('home') —— 返回一个字符串
2. render(request,'index.html') —— 返回一个具体的页面(tenplates写好的)
3. redirect(跳转的URL) ——重定向 响应头 location:'跳转的地址'
from django.shortcuts import HttpResponse, render, redirect
解释:内部传入一个字符串参数,返回给浏览器。
例如:
def index(request):
# 业务逻辑代码
return HttpResponse("OK")
除request参数外还接受一个待渲染的模板文件和一个保存具体数据的字典参数。
将数据填充进模板文件,最后把结果返回给浏览器。(相似于咱们上面用到的jinja2)
例如:
def index(request):
# 业务逻辑代码
return render(request, "index.html", {"name": "alex", "hobby": ["烫头", "泡吧"]})
接受一个URL参数,表示跳转到指定的URL。
例如:
def index(request):
# 业务逻辑代码
return redirect("/home/")
注释:
l /home/ 加/表示从根开始跳转: url 127.0.0.1:8000/home
l home/表示在原有url上拼接: 127.0.0.1:8000/index/home
l 能够接完整url
return redirect("http://www.baidu.com")
request.path_info ——》URL路径
request.method ——》请求方式
request.POST ——》POST提交的数据 { }
request.GET ——》URL上的参数 /login/?username=alex&passwor=123
获取url访问路径
appo1.views.py
def index(request):
print(request.path_info)
return HttpResponse('<h1>这是管理页面<\h1>')
输出:
/index/
[20/Sep/2018 14:01:37] "GET /index/ HTTP/1.1" 200 27
解释:获取请求方式
例:获取用户输入POST信息
app01.views.py
#定义登陆页面
def login(request):
if request.method == 'POST':
print(request.POST)
username = request.POST.get('username','') è get获取字典值不报错,并定义返回值 ‘ ’为空
password = request.POST.get('password','')
if username == 'lili' and password == '123456':
return HttpResponse('登陆成功')
else:
return HttpResponse('登陆失败')
return render(request, 'login.html')
输出
[20/Sep/2018 14:44:12] "POST /login/ HTTP/1.1" 200 12
<QueryDict: {'username': ['wang'], 'password': ['123']}>
create database django1
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
改成
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',èè支持的数据库类型
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
'NAME': 'django2',
'USER': 'root',
'PASSWORD': '',
'HOST': '127.0.0.1',
'PORT': 3306,
}
}
在项目同名的文件夹下的__init__.py中写代码:
import pymysql
pymysql.install_as_MySQLdb()
在app下的models.py中写类:
class Publisher(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=16)
python manage.py makemigrations # 保存APP下的models.py的变动记录
pyhton manage.py migrate # 将变动记录同步到数据库中
注意:指定app 默认全部注册的app根据modle 来记录来配置数据库记录资源
python manage.py makemigrations app01 针对app01作数据变动迁移 默认是setting登记过的
获取全部数据
models.Publisher.objects.all() —— 》 queryset 对象列表
获取知足条件的全部数据数据
models.Publisher.objects.filter(name='xxx') —— 》 queryset 对象列表
排序
models.Publisher.objects.all().order_by('id') —— 》 queryset 对象列表 升序
models.Publisher.objects.all().order_by('-id') —— 》 queryset 对象列表 降序序
获取一个对象
models.Publisher.objects.get(nid=1)
# 获取不到或者获取多个就报错
models.Publisher.objects.create(name='xxxxx') —— 》成功插入的对象
models.Publisher.objects.filter(nid=nid).delete() ——》 删除知足条件的全部对象
models.Publisher.objects.get(nid=nid).delete() ——》 删除对应的对象
pub_obj = models.Publisher.objects.get(nid=nid)
pub_obj.name = 'xxxx'
pub_obj.save() # 写入数据库