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名稱寫上去即可 ] - 在database中配置數據庫信息
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':'庫名', 'USER':'mysql賬號名稱', 'PASSWORD':'mysql密碼', 'HOST':'127.0.0.1', } }
- 在install_app中配置連接的app
- __init__.py配置
import pymysql pymysql.install_as_MySQLdb()
- 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
- 增
- 單條數據
方法一:models.表名.objects.create(字段1=值1,字段2=值2........) 方法二:dict = {'字段1':值,'字段2':值.........};models.表名.objects.create(**dict) - 多條數據
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)
- 單條數據
- 刪
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 models.B.objects.all().values('A__id') # 方法2 res = models.B.objects.all() for b in res: print(b.a_set.id) #### 表名小寫_set
高級查詢:
- 字段名過濾
''' 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)
- 區間 between...and
# where id between 4 and 8 [4,8] res = models.表名.objects.filter(字段名__range=[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") #忽略大小寫
- 數據條數 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()
- 排序 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) - 分頁 limit
# limit 1, 3 分頁 res = models.UserInfo.objects.all()[1:4] #因為獲取對象是列表所有切片即可
- 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用&鏈接
- F
from django.db.models import F models.UserInfo.objects.update(name=F('name')+1) #字段名稱都加1 - 原生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) - 去重 distinct
models.UserInfo.objects.values("name", 'age').distinct() #前面values有多少個就對多少個值進行去除
【注】
print(res.query) 查看上述代碼生成的sql語句
