Python Web(一)

 Infi-chu:php

http://www.cnblogs.com/Infi-chu/css

1、Web框架html

1.socket網絡編程python

  • 架構:C/S
  • 協議:TCP/UDP
  • 傳輸層

2.Web應用mysql

  • 架構:B/S
  • 協議:HTTP
  • 應用層

2、HTTP協議web

1.請求、響應ajax

  • 請求頭
  • 請求體
  • 響應頭
  • 響應體

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.響應頭中的相關參數sql

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: 服務器暫時沒法執行

3、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',
          }
      }
      
  • __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語句
相關文章
相關標籤/搜索