Python Web(一)
Infi-chu:
http://www.cnblogs.com/Infi-chu/
一、Web框架
1.socket网络编程
- 架构:C/S
- 协议:TCP/UDP
- 传输层
2.Web应用
- 架构:B/S
- 协议:HTTP
- 应用层
二、HTTP协议
1.请求、响应
- 请求头
- 请求体
- 响应头
- 响应体
2.请求头中的相关参数
- 浏览器支持的内容
- Accept:客户端接收什么类型的响应
- Accept-Charset:浏览器可以接收的字符集
- Accept-Encoding:浏览器能够进行解码的数据编码方式
- Accept-Language:浏览器希望的语言种类
- 重要的交互参数
- Cookie:客户端的Cookie就是通过这个报文头属性传给服务端的后台
- Referer:请求的来源URL
- Host:初始URL中的IP和PORT
- Cache-control:对缓存进行控制
- User-Agent:发起请求来源
- 其他参数
- If-Modified-Since:If-Modified-Since:只有当所请求的内容在指定的日期之后又经过修改才返回它,否则返回304“Not Modified”应答
- Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即使它是代理服务器而且已经有了页面的本地拷贝
- UA-Pixels,UA-Color,UA-OS,UA-CPU:由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操作系统和CPU类型
- Authorization:授权信息,通常出现在对服务器发送的WWW-Authenticate头的应答中
- Connection:表示是否需要持久连接。如果Servlet看到这里的值为“Keep-Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久连接),它就可以利用持久连接的优点,当页面包含多个元素时(例如Applet,图片),显著地减少下载所需要的时间。要实现这一点,Servlet需要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,然后在正式写出内容之前计算它的大小
- Content-Length:表示请求消息正文的长度
3.响应头中的相关参数
Header | 解释 | 示例 |
---|---|---|
Accept-Ranges | 表明服务器是否支持指定范围请求及哪种类型的分段请求 | Accept-Ranges: bytes |
Age | 从原始服务器到代理缓存形成的估算时间(以秒计,非负) | Age: 12 |
Allow | 对某网络资源的有效的请求行为,不允许则返回405 | Allow: GET, HEAD |
Cache-Control | 告诉所有的缓存机制是否可以缓存及哪种类型 | Cache-Control: no-cache |
Content-Encoding | web服务器支持的返回内容压缩编码类型。 | Content-Encoding: gzip |
Content-Language | 响应体的语言 | Content-Language: en,zh |
Content-Length | 响应体的长度 | Content-Length: 348 |
Content-Location | 请求资源可替代的备用的另一地址 | Content-Location: /index.htm |
Content-MD5 | 返回资源的MD5校验值 | Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== |
Content-Range | 在整个返回体中本部分的字节位置 | Content-Range: bytes 21010-47021/47022 |
Content-Type | 返回内容的MIME类型 | Content-Type: text/html; charset=utf-8 |
Date | 原始服务器消息发出的时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
ETag | 请求变量的实体标签的当前值 | ETag: “737060cd8c284d8af7ad3082f209582d” |
Expires | 响应过期的日期和时间 | Expires: Thu, 01 Dec 2010 16:00:00 GMT |
Last-Modified | 请求资源的最后修改时间 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT |
Location | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 | Location: http://www.zcmhi.com/archives/94.html |
Pragma | 包括实现特定的指令,它可应用到响应链上的任何接收方 | Pragma: no-cache |
Proxy-Authenticate | 它指出认证方案和可应用到代理的该URL上的参数 | Proxy-Authenticate: Basic |
refresh | 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) | Refresh: 5; url=http://www.atool.org/httptest.php |
Retry-After | 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 | Retry-After: 120 |
Server | web服务器软件名称 | Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) |
Set-Cookie | 设置Http Cookie | Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 |
Trailer | 指出头域在分块传输编码的尾部存在 | Trailer: Max-Forwards |
Transfer-Encoding | 文件传输编码 | Transfer-Encoding:chunked |
Vary | 告诉下游代理是使用缓存响应还是从原始服务器请求 | Vary: * |
Via | 告知代理客户端响应是通过哪里发送的 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 警告实体可能存在的问题 | Warning: 199 Miscellaneous warning |
WWW-Authenticate | 表明客户端请求实体应该使用的授权方案 | WWW-Authenticate: Basic |
X-Powered-By | 由语言解析器或者应用程序框架输出的,这个值的意义用于告知网站是用何种语言或框架编写的 | X-Powered-By: ASP.NET |
4.响应行书写
版本协议+响应码+附加信息\r\n\r\n响应体
eg.
HTTP/1.1 200 OK\r\n\r\n响应体
响应码:
- 1xx:提示信息,表示请求已经接收
- 2XX:响应成功
- 3xx:响应需要定向(重新记载链接第三方链接)
- 4xx:客户端错误
- 5xx:服务器端错误
常用响应码
- 200:成功
- 404;请求内容不存在
- 401:没有访问权限
- 500:服务器未知错误
- 503: 服务器暂时无法执行
三、Django
1.安装
- pip3 install django==版本号
2.创建
- 命令行创建工程:
- django-admin startproject 项目名称
- pycharm直接创建Django项目
3.目录结构
- project名的文件夹:
- settings.py:配置文件主要设置一些路径
- urls.py:路由映射关系,主要进行一些逻辑和网站的相关显示
- wsgi.py:socket服务端文件
- manage.py:管理文件
- templates:主要用来放HTML模板的地方
- static:css、js等相关文件
4.设置:
加载css、js相关文件配置:
创建static文件夹,将css、js等文件放入
- STATIC_URL = '/static/'
- STATICFILES_DIRS = (
- os.path.join(BASE_DIR, 'static'),
- )
- #如果,少了加载css会报500的错误,如果么有配置STATICFILES_DIRS会报404的错误
模块加载:
- 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',
- ]
读取HTML文件配置:
- 'DIRS': [os.path.join(BASE_DIR, 'templates')]
非本机访问:
- ALLOWED_HOSTS = ['指定ip1','指定ip2']
- ALLOWED_HOSTS = ['*'] #全部ip
4.启动
命令行:
python manage.py runserver ip:port
pycharm中:
修改Edit Configuration
5.Django模板
块定义:
- {% block 名字定义 %}
- {% endblock %}
导入模板
- {% extends '模板的文件名称' %}
- {% block 名字定义 %}
- 模板内添加的内容
- {% endblock %}
6.Cookies
用于验证登录等信息
相关参数:
key:cookie的key值
value:cookie的value值
max_age: 超时时间就是在浏览器缓存中保留多少时间 单位是s 例子:10s
expires:作用于max_age类似如果值输入一个数字代表几天,如果输入具体时间格式为2019-9-12代表这天失效
path /代表全部生效 ,/aa/表示只在aa所在的域生效
domain: 域名表示cookie只在某个域名生效
secure: 对于cookies里面数据进行加密,默认为 flase为http协议,加密为ture为https协议
httponly: true 代表不能使用js获取cookie
通过JS获得cookies我们可以在f12里输入document.cookie
获得
Django设置Cookies
- obj.set_cookie(key, value)
- set_signed_cookie(key, val, salt)
7.Django APP分组
创建APP:
- python manage.py startapp app名
app内文件:
migrations
:模型操作的迁移文件admin.py
:django admin的时候会用apps.py
:注册文件models.py
:写表生成的代码tests.py
:测试文件views.py
:视图文件,一般业务逻辑会写在其中urls.py
:格式与主urls.py一样复制过来即可
主urls.py:
- from django.conf.urls import url, include
- urlpatterns = [
- url(r'^test1/', include("test1.urls")),
- url(r'^test2/', include("test2.urls")),
- url(r'^test3/', include("test3.urls")),
- ]
分urls.py:
- from django.conf.urls import url
- from test1 import views
- urlpatterns = [
- url(r'^get_test1/', views.get_test1) #其域名为/test1/get_test1/,而不是/get_test1/
- ]
路由分发:
urls.py
- url(r'^test/(\w+)/(\w+)/', views.test),
- url(r'^test1/(?P<id>\w+)/(?P<name>\w+)/', views.test1),
views.py
- def test(request, name, id):
- print(id, name)
- return HttpResponse('test')
- def test1(request, name, id):
- print(id, name)
- return HttpResponse('test')
【注】
- 如果没有?P的约束, 传参的时候, 会根据顺序来获取参数对应的值
- 而如果有约束的话, 传参的时候, 会固定的将获取的值传给所对应的的约束
定制404 页面:
urls.py
- url(r'^', views.notfound),
views.py
- def notfound(request);
- return render(request, "404.html")
利用正则表达式以及name关键字反向路由
urls.py
- url(r'^login.*?/', views.login, name='xxx'),
login.html
- form action="{% url "xxx" %}" method="post">
- <input type="text">
- </form>
【注】
当我们输入url 为loginXXXXXXXXXXXXXX的时候网页上form表单的url会自动变成login
如果url(r'^login11', views.login, name='xxx'),上form表单的url会自动变成login11
8.FBV&CBV
- FBV(function based views):使用函数来处理业务逻辑
- CBV(class bassed views):使用类来处理业务逻辑
eg.
urls.py
- url(r'^login/', views.Login.as_view()), #类名.as_view()
views.py
- from django.views import View
- class Login(View):
- def get(self, request): #方法里必须有request来接受传过来的值不然会报错
- return render(request, "login.html")
- def post(self, request):
- pass
当请求过来时,会优先判断请求方法,如果是GET就使用get函数,如果是POST就是用post函数
继承View类的时候,会自动对传来的参数进行判断
【注】
- form表单的方式, 只支持GET/POST
- ajax的方式, 全部支持
9.ORM
- 创建项目
- settings.py配置
- 在install_app中配置连接的app
- INSTALLED_APPS = [
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'app_mysql.apps.AppMysqlConfig', #这个是我们pycharm创建时候自动帮我们注册的就是app配置
- 'app_mysql', #如果有新的或者命令行创建的app我们只要这这里面把app名称写上去即可
- ]
- INSTALLED_APPS = [
- 在database中配置数据库信息
- DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.mysql',
- 'NAME':'库名',
- 'USER':'mysql账号名称',
- 'PASSWORD':'mysql密码',
- 'HOST':'127.0.0.1',
- }
- }
- DATABASES = {
- 在install_app中配置连接的app
- __init__.py配置
- import pymysql
- pymysql.install_as_MySQLdb()
- import pymysql
- models.py配置
- from django.db import models
- # Create your models here.
- class test1(models.Model):
- ### 主键自增id不用写, 默认会加上
- name = models.CharField(max_length=30,null=True)
- class test2(models.Model):
- name = models.CharField(max_length=30, null=True)
- bigsb = models.ForeignKey('sb',id)
- class test3(models.Model):
- name = models.CharField(max_length=30,null=True)
- 生成表单语句
- python manage.py makemigrations
- python manmge.py migrate
- python manage.py makemigrations
- 增
- 单条数据
- 方法一:models.表名.objects.create(字段1=值1,字段2=值2........)
- 方法二:dict = {'字段1':值,'字段2':值.........};models.表名.objects.create(**dict)
- 方法一:models.表名.objects.create(字段1=值1,字段2=值2........)
- 多条数据
- info = [
- models.UserInfo(name='root1', age=34, ut_id=1),
- models.UserInfo(name='root2', age=35, ut_id=2),
- models.UserInfo(name='root3', age=36, ut_id=1),
- models.UserInfo(name='root4', age=37, ut_id=3),
- models.UserInfo(name='root5', age=32, ut_id=1),
- ]
- models.UserInfo.objects.bulk_create(info)
- info = [
- 单条数据
- 删
- models.表名.objects.filter(满足的条件).delete()
- 改
- models.表名.objects.filter(满足的条件).update(name='lll', age=23)
- 查
- models.UserType.objects.all().values()
有子键关系的查询:
- 正向:
- # 方法1
- models.A.objects.all().values('ud__id')
- # 方法2
- res = models.A.objects.all()
- for a in res:
- print(a.ud.id)
- # 方法1
- 反向:
- # 方法1
- models.B.objects.all().values('A__id')
- # 方法2
- res = models.B.objects.all()
- for b in res:
- print(b.a_set.id) #### 表名小写_set
- # 方法1
高级查询:
- 字段名过滤
- '''
- filter满足条件的
- exclude不满足条件
- '''
- #id等于3的
- models.表名.objects.filter(id=3).values()
- #id不等于3的
- models.表名.objects.exclude(id=3).values()
- '''
- 关于filter与exclude里面填写的参数
- 等于:字段名=值
- 大于:字段名__gt=值
- 大于等于:字段名__gte=值
- 小于:字段名__lt=值
- 小于等于:字段名__lte=值
- '''
- '''
- 成员 in not in
- res = models.表名.objects.filter(字段名__in=[2,4,5]) # where id in (2,4,5)
- res = models.表名.objects.exclude(字段名__in=[1,2]) # where id not in (1,2)
- res = models.表名.objects.filter(字段名__in=[2,4,5]) # where id in (2,4,5)
- 区间 between...and
- # where id between 4 and 8 [4,8]
- res = models.表名.objects.filter(字段名__range=[4,8])
- # where id between 4 and 8 [4,8]
- 模糊查询 like
- # where name like 'a%'
- res = models.表名.objects.filter(字段名__startswith="a")
- res = models.表名.objects.filter(字段名__istartswith="a") #忽略大小写
- # where name like '%a'
- res = models.表名.objects.filter(字段名__endswith="a")
- res = models.表名.objects.filter(字段名__iendswith="a") #忽略大小写
- # where name like '%a%'
- res = models.表名.objects.filter(字段名__contains="a")
- res = models.表名.objects.filter(字段名__icontains="a") #忽略大小写
- # where name like 'a%'
- 数据条数 count
- # select count(*) from userinfo where id>3;
- # select count(id) from userinfo where id>3;
- #用sql语句查询数据条数尽量不要查count(*)查主键会快很多
- res = models.UserInfo.objects.filter(id__gt=3).count()
- # select count(*) from userinfo where id>3;
- 排序 order by
- #升序
- res = models.表名.objects.order_by('字段名称')
- #降序
- res = models.表名.objects.order_by('-字段名称')
- #多个条件进行排序
- res = models.表名.objects.order_by('字段1','字段2') #当字段1相同是会更具字段2进行排序
- #升序
- 分组 group by
- # select id, sum(age) as s, username from userinfo group by username
- from django.db.models import Count, Min, Max, Sum
- res = models.UserInfo.objects.values("name").annotate(s=Sum('age'))
- # select id, sum(age) as s, username from userinfo group by username having s > 50;
- res = models.UserInfo.objects.values("name").annotate(s=Sum('age')).filter(s__gt=50)
- # select id, sum(age) as s, username from userinfo group by username
- 分页 limit
- # limit 1, 3 分页
- res = models.UserInfo.objects.all()[1:4]
- #因为获取对象是列表所有切片即可
- # limit 1, 3 分页
- last/first
- # 第一条:
- res = models.表名.objects.first()
- # 最后一条:
- res = models.表名.objects.last()
- # 第一条:
- only/defer
- '''
- 只查某个字段:only('字段名称')
- 除某个字段以外的所有字段:defer('字段名')
- 注意:主键id不管怎么样都会查
- '''
- '''
- and/or
- # 只有and
- #id等于3and名字等于a
- models.表名.objects.filter(id=3,and name='a').values()
- # 只有or
- # Q
- from django.db.models import Q
- res = models.UserInfo.objects.filter(Q(id__gt=3) | Q(name='zekai')) #or用|链接
- # 有and和or
- # Q
- from django.db.models import Q
- res = models.UserInfo.objects.filter( Q(Q(id__gt=3) | Q(name='zekai')) & Q(age=23) ) and用&链接
- # 只有and
- F
- from django.db.models import F
- models.UserInfo.objects.update(name=F('name')+1) #字段名称都加1
- from django.db.models import F
- 原生SQL 类似pycharm
- from django.db import connection, connections
- cursor = connection.cursor() # cursor = connections['default'].cursor()
- cursor.execute("""SELECT * from auth_user where id = %s""", [1])
- row = cursor.fetchone()
- print(row)
- from django.db import connection, connections
- 去重 distinct
- models.UserInfo.objects.values("name", 'age').distinct() #前面values有多少个就对多少个值进行去除
【注】
- print(res.query) 查看上述代码生成的sql语句
Python Web(一)的更多相关文章
- Redis的Python实践,以及四中常用应用场景详解——学习董伟明老师的《Python Web开发实践》
首先,简单介绍:Redis是一个基于内存的键值对存储系统,常用作数据库.缓存和消息代理. 支持:字符串,字典,列表,集合,有序集合,位图(bitmaps),地理位置,HyperLogLog等多种数据结 ...
- Python Web 方向(一)
Python Web 方向(一) --------Django站点创建 文章地址:http://www.cnblogs.com/likeli/p/5821744.html Python版本:2.7 推 ...
- 浅谈五大Python Web框架
转载:http://feilong.me/2011/01/talk-about-Python-web-framework 说到Web Framework,Ruby的世界Rails一统江湖,而Pytho ...
- nginx上部署python web
nginx上部署python web http://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
- 全面解读python web 程序的9种部署方式
转载自鲁塔弗的博客,本文地址http://lutaf.com/141.htm python有很多web 开发框架,代码写完了,部署上线是个大事,通常来说,web应用一般是三层结构 web serve ...
- Python Web 开发的十个框架【转载】
Python 是一门动态.面向对象语言.其最初就是作为一门面向对象语言设计的,并且在后期又加入了一些更高级的特性.除了语言本身的设计目的之外,Python标准 库也是值得大家称赞的,Python甚至还 ...
- tornado 学习笔记2 Python web主流框架
2.1 Django 官方网址:https://www.djangoproject.com/ 简介:Django is a high-level Python Web framework that e ...
- python web框架——扩展Django&tornado
一 Django自定义分页 目的:自定义分页功能,并把它写成模块(注意其中涉及到的python基础知识) models.py文件 # Create your models here. class Us ...
- 5个最好的Python Web开发框架
Python是最受欢迎的和最有效率的开发语言之一.Python能让你更快完成工作,并且更有效地集成系统.Python是动态的面向对象的语言.即便你刚刚开始学习Python,也立即就能获得生产力上的提升 ...
- The Python web services developer: XML-RPC for Python
原文地址:http://www.ibm.com/developerworks/webservices/library/ws-pyth10/index.html 摘要:概括地说,您可以将 XML-RPC ...
随机推荐
- 从《彩色圆环》一题探讨一类环上dp的解法
清橙A1202 bzoj2201 bsoj4074 试题来源 2010中国国家集训队命题答辩 问题描述 小A喜欢收集宝物.一天他得到了一个圆环,圆环上有N颗彩色宝石,闪闪发光.小A很爱惜这个圆环,天天 ...
- 62-Weave 网络结构分析
上一节我们安装并创建了 Weave 网络,本节将部署容器并分析网络结构. 在 host1 中运行容器 bbox1: eval $(weave env) docker run --name bbox1 ...
- Builder模式的目的是解耦构建过程,为什么要用内部类?
还没有看过Builder模式的作用,看过一篇介绍Builder模式的文章,这里是关于Builder模式的思考:思考是否有比新建一个内部类更好的方法,首先想到的是 package xyz.n490808 ...
- Node.js / Python 日志
一.Node.js 日志 1.原生 Node.js 原生方法其实很简单,就四个: // 输出到 stdout console.log() console.info() = console.log() ...
- 字符串模式匹配——KMP算法
KMP算法匹配字符串 朴素匹配算法 字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就 ...
- ServerSocket类的常用方法
1.accept:侦听并接受此套接字的连接:此方法在连接传入之前一直阻塞. 2.setSoTimeout(timeout)方法的作用时设置超时时间,通过指定超时timeout值启用/禁用超时功能,以m ...
- angular8自定义管道、指令以及获取dom值
版本: 1.自定义管道: example: 定义一个*ngFor 可以获取key值的管道 keyObject.pipe.ts // key value 管道 import { Pipe, PipeTr ...
- 欢迎大家Follow me!微软MVP罗勇(Dynamics CRM方向2015-2018年)欢迎您!
我是一名八零后,来自湖南乡村,2006年毕业于大连大学工商管理专业,主要靠自学走上了编程之路.从2012年开始接触Dynamics CRM 2011,一直从事Dynamics CRM方面工作,熟悉Dy ...
- 一图了解 CODING 2.0:企业级持续交付解决方案
近日,CODING 在 KubeCon 2019 上海站上正式推出了 DevOps 的一站式解决方案:CODING 2.0. CODING 2.0 进行了产品.产品理念.功能.首页的升级,对用户服务进 ...
- java 后端与前端Date类型与String类型互相转换(使用注解)
后端返回的类型中,直接定义Date类型,加上此注解,直接将Date类型转成自定义的格式给前端 class TestDateOutput{ @JsonFormat(pattern = "yyy ...