1. 程式人生 > >Python自動化開發學習的第十一周----WEB框架--Django基礎

Python自動化開發學習的第十一周----WEB框架--Django基礎

修改表結構 add int cfi cit eve rom pos settings

WEB框架的本質

對於所有的Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。

#!/usr/bin/env python
#coding:utf-8
  
import socket
  
def handle_request(client):
    buf = client.recv(1024)
    client.send("HTTP/1.1 200 OK\r\n\r\n")
    client.send("Hello, Seven")
  
def main():
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind((‘localhost‘,8000))
    sock.listen(5)
  
    while True:
        connection, address = sock.accept()
        handle_request(connection)
        connection.close()
  
if __name__ == ‘__main__‘:
    main()

上述通過socket來實現了其本質,而對於真實開發中的python web程序來說,一般會分為兩部分:服務器程序和應用程序。服務器程序負責對socket服務器進行封裝,並在請求到來時,對請求的各種數據進行整理。應用程序則負責具體的邏輯處理。為了方便應用程序的開發,就出現了眾多的Web框架,例如:Django、Flask、web.py 等。不同的框架有不同的開發方式,但是無論如何,開發出的應用程序都要和服務器程序配合,才能為用戶提供服務。這樣,服務器程序就需要為不同的框架提供不同的支持。這樣混亂的局面無論對於服務器還是框架,都是不好的。對服務器來說,需要支持各種不同框架,對框架來說,只有支持它的服務器才能被開發出的應用使用。這時候,標準化就變得尤為重要。我們可以設立一個標準,只要服務器程序支持這個標準,框架也支持這個標準,那麽他們就可以配合使用。一旦標準確定,雙方各自實現。這樣,服務器可以支持更多支持標準的框架,框架也可以使用更多支持標準的服務器。

WSGI(Web Server Gateway Interface)是一種規範,它定義了使用python編寫的web app與web server之間接口格式,實現web app與web server間的解耦。

python標準庫提供的獨立WSGI服務器稱為wsgiref。

from wsgiref.simple_server import make_server
 
 
def RunServer(environ, start_response):
    start_response(‘200 OK‘, [(‘Content-Type‘, ‘text/html‘)])
    return [bytes(‘<h1>Hello, web!</h1>‘, encoding=‘utf-8‘), ]
 
 
if __name__ == ‘__main__‘:
    httpd = make_server(‘‘, 8000, RunServer)
    print("Serving HTTP on port 8000...")
    httpd.serve_forever()

Python的WEB框架有Django、Tornado、Flask 等多種,Django相較與其他WEB框架其優勢為:大而全,框架本身集成了ORM、模型綁定、模板引擎、緩存、Session等諸多功能。

Django工程前基本配置

一、安裝Django

  pip install django

二、創建Django工程 

  • 終端命令:django-admin startproject sitename(工程名稱)
  • IDE創建Django程序時,本質上都是自動執行上述命令

三、程序目錄

技術分享圖片

mysite
- mysite # 對整個程序進行配置
- init
- settings # 配置文件
- url # URL對應關系
- wsgi # 遵循WSIG規範,uwsgi + nginx
- manage.py # 管理Django程序:
- python manage.py
- python manage.py startapp xx
- python manage.py makemigrations
- python manage.py migrate

   -templates #放置網頁內容

# 運行Django功能
python manage.py runserver 127.0.0.1:8000

四、創建app

  # 創建app
python manage.py startapp cmdb
python manage.py startapp openstack
python manage.py startapp xxoo....

技術分享圖片

app:
migrations 數據修改表結構
admin Django為我們提供的後臺管理
apps 配置當前app
models ORM,寫指定的類 通過命令可以創建數據庫結構
tests 單元測試
views 業務代碼

五、工程前的默認配置

1.配置模板的路徑

settings.py

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‘,
]

ROOT_URLCONF = ‘s14day19.urls‘

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‘,
            ],
        },
    },
]

2.配置靜態目錄

新建static目錄

settings.py中添加

STATIC_URL = ‘/static/‘
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,"static"),
)

下面就可以編寫程序了

編寫程序

Django請求生命周期
-> URL對應關系(匹配) -> 視圖函數 -> 返回用戶字符串
-> URL對應關系(匹配) -> 視圖函數 -> 打開一個HTML文件,讀取內容

路由系統

1.url

urls.py

from django.contrib import admin
from django.urls import path
from cmdb import views

urlpatterns = [
    path(‘admin/‘, admin.site.urls),
    path(‘login/‘, views.login),
    path(‘home/‘, views.home),

]

2.基於正則表達式的url

re_path(‘detail-(\d+).html‘, views.detail),
#一個函數對應多個頁面
re_path(‘detail-(\d+)-(\d+).html‘, views.detail),  
#nid ,uid  一定按照順序
re_path(‘detail-(?P<nid>\d+)-(?P<uid>\d+).html‘, views.detail),
#綁定nid和uid
技術分享圖片
 1 # def detail(request,nid):
 2 #     return HttpResponse(nid)
 3 #     # n = request.GET.get("nid")
 4 #
 5 #     # info = USER_DICT[nid]
 6 #     # return render(request,"detail.html",{"info":info})
 7 # def detail(request, nid):
 8 #     info = USER_DICT[nid]
 9 #     return render(request,"detail.html",{"info":info})
10 def detail(request,nid,uid):
11     print(nid,uid)
12 
13     return HttpResponse(nid)
14     # info = USER_DICT[nid]
15     # return render(request,"detail.html",{"info":info})
views 技術分享圖片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     {{ user_dict.user }}
 9     <ul>
10         {% for k,row in user_dict.items %}
11             <li><a target="_blank" href="/detail-{{ k }}.html">{{ row.user }}</a></li>
12         {% endfor %}
13     </ul>
14     <!--
15     <ul>
16         {% for k,row in user_dict.items %}
17             <li><a target="_blank" href="/detail/?nid={{ k }}">{{ row.user }}</a></li>
18         {% endfor %}
19     </ul>
20     -->
21 
22 </body>
23 </html>
index.html 技術分享圖片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <h1>詳細信息</h1>
 9     <h3>用戶名:{{ info.user }}</h3>
10     <h3>密碼:{{ info.password }}</h3>
11     <h3>郵箱:{{ info.email }}</h3>
12 
13 </body>
14 </html>
detail.html

3.為路由映射設置名稱

對URL路由關系進行命名, ***** 以後可以根據此名稱生成自己想要的URL *****

urls.py

urlpatterns = [
    path(‘indfasfasdfdex/‘, views.index, name="index1"),
    re_path(‘ind/(\d+)/‘, views.index, name="index2"),
    re_path(‘ind/(\d+)/(\d+)/‘, views.index, name="index3"),
    re_path(‘ind/(?P<nid>\d+)/(?P<uid>\d+)/‘, views.index, name="index4"),
]

views.py

def func(request, *args, **kwargs):
	from django.urls import reverse
			
	url1 = reverse(‘index1‘)                                         # indefasfasdfdex/
	url2 = reverse(‘index3‘, args=(1,2,))                       # ind/1/2/
	url3 = reverse(‘index4‘, kwargs={‘pid‘: 1, "nid": 9})  #ind/1/9/

xxx.html

{% url "index1" %}                      # indfasfasdfdex/
{% url "index2" 1 2 %}                # ind/1/2/
{% url "index3" pid=1 nid=9 %}   # ind/1/9/

註:
# 當前的URL
request.path_info

4.路由分發-----多級路由

主目錄下的urls.py

urlpatterns = [
    path(‘cmdb/‘,include("app01.urls")),
    path(‘monitor/‘,include("app02.urls"))

]

app01下添加urls.py

from django.urls import path,re_path
from app01 import views

urlpatterns = [

    path(‘index/‘, views.index),
    
]

app02下添加urls.py

from django.urls import path,re_path
from app02 import views

urlpatterns = [

    path(‘index/‘, views.index),

]

視圖

views.py

def func(request):
# 包含所有的請求數據
...
return HttpResponse(‘字符串‘)
return render(request, ‘index.html‘, {‘‘})
retrun redirect(‘URL‘)

from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.shortcuts import redirect

USER_LIST=[
    {"username":"zhangsan","gender":"man","email":"[email protected]"},
    {"username":"zhangsi","gender":"woman","email":"[email protected]"},
    {"username":"zhangwu","gender":"man","email":"[email protected]"},
]

def home(request):
    print(request.method)
    if request.method == "POST":
        user=request.POST.get("username")
        gen=request.POST.get("gender")
        ema=request.POST.get("email")
        temp = {"username":user,"gender":gen,"email":ema}
        USER_LIST.append(temp)
    return render(request,"home.html",{"user_list":USER_LIST})


def login(request):
    # f = open("templates/login.html","r",encoding="utf-8")
    # date = f.read()
    # f.close()

    error_msg = " "
    if request.method == "POST":
        user = request.POST.get("user",None)
        pwd = request.POST.get("pwd",None)

        if user=="root" and pwd=="123":
            return redirect("http://www.baidu.com")
        else:
            error_msg = "用戶名密碼錯誤"

    return render(request,"login.html",{"error_msg":error_msg})

獲取多數據和文件上傳

技術分享圖片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8     <form action="/login/" method="POST" enctype="multipart/form-data">
 9         <p>
10             <input type="text" name="user" placeholder="用戶名" />
11         </p>
12         <p>
13             <input type="password" name="password" placeholder="密碼" />
14         </p>
15         <p>
16             男:<input type="radio" name="gender" value="1"/>
17             女:<input type="radio" name="gender" value="2"/>
18         </p>
19         <p>
20             籃球:<input type="checkbox" name="faver" value="11" />
21             足球:<input type="checkbox" name="faver" value="22" />
22             排球:<input type="checkbox" name="faver" value="33" />
23         </p>
24         <p>
25             <select name="city" multiple>
26                 <option value="bj">北京</option>
27                 <option value="sh">上海</option>
28                 <option value="tj">天津</option>
29             </select>
30         </p>
31         <p>
32             <input type="file" name="filesss"/>
33         </p>
34         <p>
35             <input type="submit" value="提交" />
36         </p>
37     </form>
38 </body>
39 </html>
login.html 技術分享圖片
 1 from django.shortcuts import render,HttpResponse,redirect
 2 
 3 # Create your views here.
 4 
 5 def index(request):
 6     return HttpResponse("Welcome to Index!")
 7 
 8 def login(request):
 9     ‘‘‘if request.method == "GET":
10         return render(request, "login.html")
11     elif request.method == "POST":
12         u= request.POST.get("user")
13         p= request.POST.get("password")
14 
15         if u == "abc" and p == "123":
16             return redirect("/index/")
17         else:
18             return render(request,"login.html")
19     else:
20         return redirect("/index/")
21     ‘‘‘
22 
23     if request.method == "GET":
24             return render(request, "login.html")
25     elif request.method == "POST":
26         # v = request.POST.get("gender")
27         # print(v)
28         # v = request.POST.getlist("faver")
29         # print(v)
30         # v = request.POST.getlist("city")
31         # print(v)
32         
33         # 文件上傳
34         obj =request.FILES.get("filesss")
35         import os
36         file_path = os.path.join("upload",obj.name)
37         f= open(file_path,mode="wb")
38         for i in obj.chunks():
39             f.write(i)
40         f.close()
41 
42 
43 
44         return render(request, "login.html")
45     else:
46         return redirect("/index/")
views.py

FBV & CBV

url.py index ---> 函數名

views.py def 函數(request):................

FBV /index/ -> 函數名
CBV /index/ -> 類

from django.views import View
class Home(View):

    def get(self,request):
        print(request.method)
        return render(request,"home.html")

    def post(self,request):
        print(request.method,"post")
        return render(request, "home.html")

模板

模板語言
return render(request, ‘index.html‘, {‘li‘: [11,22,33]})

{% for item in li %}
<h1>{{item}}</h1>
{% endfor %}


*********** 索引用點 **********
<h2> {{item.0 }} </h2>

技術分享圖片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body style="margin: 0">
 8     <div style="background-color: #eeeeee;height: 50px;"></div>
 9     <form action="/home/" method="post">
10         <p>
11             <input type="text" name="username" placeholder="用戶名" />
12         </p>
13         <p>
14             <input type="text" name="gender" placeholder="性別" />
15         </p>
16         <p>
17             <input type="text" name="email" placeholder="郵箱" />
18         </p>
19         <p>
20             <input type="submit" value="提交" />
21         </p>
22     </form>
23     <div>
24         <table>
25             {% for row in user_list %}
26                 <tr>
27                     <td>{{ row.username }}</td>
28                     <td>{{ row.gender }}</td>
29                     <td>{{ row.email }}</td>
30                 </tr>
31             {% endfor %}
32         </table>
33     </div>
34 </body>
35 </html>
home 技術分享圖片
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6     <link rel="stylesheet" href="/static/commons.css" />
 7     <style>
 8         label{
 9             width: 80px;
10             text-align: right;
11             display: inline-block;
12         }
13     </style>
14 </head>
15 <body>
16         <form action="/login/" method="post">
17         <p>
18             <label for="username">用戶名:</label>
19             <input id="username" name="user" type="text" />
20         </p>
21         <p>
22             <label for="password">密碼:</label>
23             <input id="password" name="pwd" type="text" />
24             <input type="submit" value="提交" />
25             <span style="color: red">{{ error_msg }}</span>
26         </p>
27     </form>
28     <script src="/static/jquery-1.12.4.js"></script>
29 </body>
30 </html>
login

ORM操作

*******************************To Be Continue************************************

Python自動化開發學習的第十一周----WEB框架--Django基礎