关于HTTP协议:
-
浏览器往服务端发的叫 请求(request)
请求的消息格式:
请求方法 路径 HTTP/1.1\r\n
k1:v1\r\n
k2:v2\r\n
\r\n
请求数据 -
服务端往浏览器发的叫 响应(response)
响应的消息格式:
HTTP/1.1 状态码 状态描述符\r\n
k1:v1\r\n
k2:v2\r\n
\r\n
响应正文 <-- html的内容
WEB技术
1. web框架的本质:
socket服务端 与 浏览器的通信
2. socket服务端功能划分:
a. 负责与浏览器收发消息(socket通信) --> wsgiref/uWsgi/gunicorn...
b. 根据用户访问不同的路径执行不同的函数
c. 从HTML读取出内容,并且完成字符串的替换 --> jinja2(模板语言)
3. Python中 Web框架的分类:
1. 按上面三个功能划分:
1. 框架自带a,b,c --> Tornado
2. 框架自带b和c,使用第三方的a --> Django
3. 框架自带b,使用第三方的a和c --> Flask
2. 按另一个维度来划分:
1. Django --> 大而全(你做一个网站能用到的它都有)
2. 其他 --> Flask 轻量级
Django项目
-
新建Django
命令行创建:
django-admin startproject mysite
pycharm创建:- File --> New project --> 左侧选Django --> 右侧填项目路径,并且勾选python.exe,设置application name
-
新建APP
python3 manage.py startapp app01
- 新建表
python3 manage.py makemigrations
python3 manage.py migrate
-
Django项目的启动:
1. 命令行启动 在项目的根目录下(也就是有manage.py的那个目录),运行: python manage.py runserver IP:端口--> 在指定的IP和端口启动 python manage.py runserver 端口 --> 在指定的端口启动 python manage.py runserver --> 默认在本机的8000端口启动 2. PyCharm启动 点绿色的小三角,直接可以启动Django项目(前提是小三角左边是你的Django项目名)
-
配置相关 项目名/settings.py文件
1. Templates(存放HTML文件的配置) <-- 告诉Django去哪儿找我的HTML文件 2. 静态文件(css/js/图片) # 静态文件保存目录的别名 STATIC_URL = '/static/' # 所有静态文件(css/js/图片)都放在我下面你配置的文件夹中 STATICFILES_DIRS = [ os.path.join(BASE_DIR, "static"), ]
MTV模式
模型Model models.py
模板Template templates
视图View urls.py views.py
ORM
ORM的对应关系:
类 ---> 数据表
对象 ---> 数据行
属性 ---> 字段
-
Django的ORM使用详细步骤:
1. 自己动手创建数据库 create database 数据库名; 2. 在Django项目中设置连接数据库的相关配置(告诉Django连接哪一个数据库) - 数据库相关的配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 连接的数据库类型 'HOST': '127.0.0.1', # 连接数据库的地址 'PORT': 3306, # 端口 'NAME': "zrq", # 数据库名称 'USER': 'root', # 用户 'PASSWORD': '123456' # 密码 } } 3. 告诉Django用pymysql代替默认的MySQLDB 连接MySQL数据库 在项目/__init__.py文件中,写下面两句: import pymysql # 告诉Django用pymysql来代替默认的MySQLdb pymysql.install_as_MySQLdb() 4. 在app下面的models.py文件中定义一个类,这个类必须继承models.Model class 类名(models.Model):
-
常用字段
AutoField int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。 IntegerField 一个整数类型,范围在 -2147483648 to 2147483647。 CharField 字符类型,必须提供max_length参数, max_length表示字符长度。 DateField 日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。 DateTimeField 日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。 class FixedCharField(models.Field): """ 自定义的char类型的字段类 """ def __init__(self, max_length, *args, **kwargs): self.max_length = max_length super(FixedCharField, self).__init__(max_length=max_length, *args, **kwargs) def db_type(self, connection): """ 限定生成数据库表的字段类型为char,长度为max_length指定的值 """ return 'char(%s)' % self.max_length #字段参数 null 用于表示某个字段可以为空。 unique 如果设置为unique=True 则该字段在此表中必须是唯一的 。 db_index 如果db_index=True 则代表着为此字段设置数据库索引。 default 为该字段设置默认值。 时间字段独有 DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性。 auto_now_add 配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。 auto_now 配置上auto_now=True,每次更新数据记录的时候会更新该字段。 #外键字段 to 设置要关联的表 to_field 设置要关联的表的字段 related_name 反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'。 related_query_name 反向查询操作时,使用的连接前缀,用于替换表名。 on_delete 当删除关联表中的数据时,当前表与其关联的行的行为。 models.CASCADE删除关联数据,与之关联也删除 models.DO_NOTHING删除关联数据,引发错误IntegrityError models.PROTECT删除关联数据,引发错误ProtectedError models.SET_NULL删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空 models.SET_DEFAULT删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值) models.SET删除关联数据, a. 与之关联的值设置为指定值,设置:models.SET(值) b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象) db_constraint 是否在数据库中创建外键约束,默认为True。
-
ORM的增删查改
增加
models.Table.objects.create(name=“张三”)
删除
obj = models.Table.objects.get(id=delete_id)
obj.delete()
查询
res = models.Table.objects.all()
修改
obj = models.Table.objects.get(id=edit_id)
obj.name = new_name
obj.save()
模板
-
常用方法
1.{{name}} -->变量相关 2.for循环 forloop.counter 当前循环索引值1开始 forloop.counter0 当前循环索引值0开始 forloop.recounter 当前循环倒序索引值1开始 forloop.first 当前循环是不是第一次循环(布尔值) forloop.last 当前循环是不是最后一次循环(布尔值) forloop.parentloop 当前循环的外层循环 {% for i in book_list %} {{forloop.counter}} {{forloop.last}} {{i}} {% empty %} <li>没有数据执行这个</li> {% endfor %} 3.if 判断 {% if a > b %} ... {% elif a > c %} ... {% else %} ... {% endif %} 4.if ... in判断 {% if name in name_list %} ... {% endif %}
-
filter 语法{{value|filter_name:参数}}
default如果变量没有传值使用nothing作为变量值 {{value|default:'nothing'}} length 返回变量长度 {{value|length}} filesizeformat {{value|filesizeformat}} 如果value是123456789,输出117.7MB slice 切片 {{value|slice “2:-1”}} date 格式化 {{value|date “Y-m-d H:i:s“}} safe {{value|safe}} 导入自定义filter方法 #app下面新建包,包内新建app01_filter.py from django import template register = template.Library() @register.filter(name="cut") def cut(value, arg): return value.replace(arg, "") {# 先导入我们自定义filter的那个文件 #} {% load app01_filter %} {# 使用我们自定义的filter #} {{ somevariable|cut:"0" }} 中间变量with {% with name = namelist1.1 %} {{name}} {% endwith %} 注释 {# 注释内容 #}
-
母版
- 把公用的HTML部分提取出来,放到base.html文件中
- 在base.html中,通过定义block,把每个页面不同的部分区分出来
- 在具体的页面中,先继承母版
- 然后block名去指定替换母版中相应的位置
-
使用母版和继承的注意事项:
-
{% extends ‘base.html’ %} --> 母版文件:base.html要加引号
-
{% extends ‘base.html’ %} --> 必须放在子页面的第一行!!!
-
可以在base.html中定义很多block,通常我们会额外定义page-css和page-js
先继承,在拓展 {% extends 'base.html' %} {% block page-main %} 内容代码 {% endblock %} 注意继承页面中,写在block里面的代码才会执行,写在外面不执行
-
view.py相应的函数中返回的是对应的子页面文件 不是不是不是 base.html
-
-
组件
写好的一个模块HTML代码,加载方法如下
{% include ‘xxx.html’%} -
自定义simple_tag,接受的参数个数大于2
app下新建文件夹,新建文件mysimpletag.py文件,文件名自定义 from django import template register = template.Library() @register.simple_tag(name="yimi") def my_sum(arg1, arg2, arg3): return "{} {} {}".format(arg1, arg2, arg3) 在HTML文件里面的使用 {% load mysimpletag %} {% yimi 'wangzhen' 'tiancai' 'dafu' %}
-
自定义inclusion_tag,将HTML文件带上参数,插入到当前HTML文件中,和组件类似
app下新建文件夹,新建文件mysimpletag.py文件,文件名自定义 from django import template register = template.Library() @register.inclusion_tag('results.html') def show_results(n): n = 1 if n < 1 else int(n) data = ["第{}项".format(i) for i in range(1, n+1)] return {"data": data} results.html <ul> {% for i in data %} <li>{{ i }}</li> {% endfor %} </ul> HTML文件使用 {% load mysimpletag %} {% show_results 10 %}
视图函数
1. CBV(class base view)和FBV(function base view)
2. request对象
1. 之前学过的
1. request.method --> 获取请求的方法(GET、POST等)
2. request.GET --> 通常用来获取URL里面的参数
127.0.0.1:8000/edit_book/?id=1&name=yimi
request.GET --> {"id":1, "name":"yimi"}
request.GET.get("id")
3. request.POST --> 用来获取POST提交过来的数据
request.POST.get("book_name")
4. request.FILES["upload_file"].name 文件名
request.FILES["upload_file"].chunks() 文件内容
2. 补充其他常用的:
1. request.path_info --> 获取用户请求的路径(不包含IP和端口和URL参数)
2. request.body --> 请求体
3. response
基础必备三件套(求学要严谨)
1. HttpResponse --> 返回字符串内容
2. render --> 返回一个html页面
3. redirect --> 返回一个重定向(告诉浏览器再去访问另外的网址)
4. JsonResponse
data = {"name": "小黑", "age": 18}
data2 = [11, 22, 33, 44]
from django.http import JsonResponse
返回列表要加上safe=False
return JsonResponse(data2, safe=False)
路由系统(urls.py)
http://www.cnblogs.com/liwenzhou/p/8271147.html
1. 正则表达式的模糊匹配
2. 分组匹配 --> 相当于给视图函数传递位置参数
3. 分组命名匹配 --> 相当于给视图函数传递关键字参数
(两个不要混合使用)
反向解析URL
本质上就是给url匹配模式起别名,然后通过别名拿到具体的URL路径
-
怎么起别名?
在url匹配模式中,定义name=“别名”
url(r’^json99/$’, views.json_test, name=“json_test”), -
如何使用?
-
在模板语言里面使用:
{% url "别名" %} --> 得到具体的URL路径 <a href="{% url 'json_test' %}">点我</a>
-
在视图中如何使用:
在视图中如何使用: from django.urls import reverse reverse("别名") --> 得到具体的URL路径 redirect_url = reverse("json_test") return redirect(redirect_url)
-
如何传参数?
1.路由系统 位置参数 url(r'^book/([0-9]{2,4})/([a-zA-Z]{2})/$', views.book, name="book"), 关键字参数 url(r'^book/(?P<year>[0-9]{4})/(?P<title>[a-zA-Z]{2})/$', views.book, name="book") 2. 视图传参数 传位置参数: redirect_url = reverse("别名", args=(2018, "nb")) return redirect(redirect_url) 传关键字参数: redirect_url = reverse("别名" kwargs={"year": 2018, "title": "nb"}) return redirect(redirect_url) 3. 模板传参数: {% url "别名" 2018 "nb" %} {% url "别名" year=2018 title='nb' %} 链接传参数 <a href="{% url 'book' year=2018 title='nb' %}">测试</a> 视图接收参数 def test(request, year, title): print("year:", year, type(year)) print("title:", title) return HttpResponse("成功") 4. namespace 为了防止不同的app下面的url匹配模式有重复的别名 主路由 import app01,app02 url(r'^car/', include(('app01.urls','app01'), namespace="car"),), url(r'^house/', include(('app02.urls','app02'), namespace="house")), app01 url(r'^home/', views.home, name="home"), app02 url(r'^home/', views.home, name="home"), 5.模板语言使用 <a href="{% url 'car:home' %}">买车主页,点我</a> <a href="{% url 'house:home' %}">买房主页,点我</a>
-