Python自动化开发学习的第十一周----WEB框架--Django基础

Posted 薛定谔的猫

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python自动化开发学习的第十一周----WEB框架--Django基础相关的知识,希望对你有一定的参考价值。

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.配置模板的路径

 1 MIDDLEWARE = [
 2     \'django.middleware.security.SecurityMiddleware\',
 3     \'django.contrib.sessions.middleware.SessionMiddleware\',
 4     \'django.middleware.common.CommonMiddleware\',
 5     # \'django.middleware.csrf.CsrfViewMiddleware\',
 6     \'django.contrib.auth.middleware.AuthenticationMiddleware\',
 7     \'django.contrib.messages.middleware.MessageMiddleware\',
 8     \'django.middleware.clickjacking.XFrameOptionsMiddleware\',
 9 ]
10 
11 ROOT_URLCONF = \'s14day19.urls\'
12 
13 TEMPLATES = [
14     {
15         \'BACKEND\': \'django.template.backends.django.DjangoTemplates\',
16         \'DIRS\': [os.path.join(BASE_DIR, \'templates\')]
17         ,
18         \'APP_DIRS\': True,
19         \'OPTIONS\': {
20             \'context_processors\': [
21                 \'django.template.context_processors.debug\',
22                 \'django.template.context_processors.request\',
23                 \'django.contrib.auth.context_processors.auth\',
24                 \'django.contrib.messages.context_processors.messages\',
25             ],
26         },
27     },
28 ]
settings.py

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),

]

 5.默认值

url(r\'^manage/(?P<name>\\w*)\', views.manage,{\'id\':333}),

 6.命名空间

project.urls.py

from django.conf.urls import url,include
 
urlpatterns = [
    url(r\'^a/\', include(\'app01.urls\', namespace=\'author-polls\')),
    url(r\'^b/\', include(\'app01.urls\', namespace=\'publisher-polls\')),
]

 app01.urls.py

from django.conf.urls import url
from app01 import views
 
app_name = \'app01\'
urlpatterns = [
    url(r\'^(?P<pk>\\d+)/$\', views.detail, name=\'detail\')
]

 app01.views.py

def detail(request, pk):
    print(request.resolver_match)
    return HttpResponse(pk)

以上定义带命名空间的url之后,使用name生成URL时候,应该如下:

  • v = reverse(\'app01:detail\', kwargs={\'pk\':11})
  • {% url \'app01:detail\' pk=12 pp=99 %}

django中的路由系统和其他语言的框架有所不同,在django中每一个请求的url都要有一条路由映射,这样才能将请求交给对一个的view中的函数去处理。其他大部分的Web框架则是对一类的url请求做一条路由映射,从而是路由系统变得简洁。

 

 

 

 

 

视图

 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":"abc@123.com"},
    {"username":"zhangsi","gender":"woman","email":"abc@123.com"},
    {"username":"zhangwu","gender":"man","email":"abc@123.com"},
]

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.获取多数据和文件上传

 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

 

2.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")

 

3.获取用户请求的相关信息以及请求头

 1 def index(request):
 2     print(type(request))
 3     
 4     from django.core.handlers.wsgi import WSGIRequest
 5     
 6     print(request.environ) #封装了请求的所有信息
 7 
 8     for k,v in request.environ.items():  #列出所有信息
 9         print(k,v)
10 
11     print(request.environ["HTTP_USER_AGENT"])
12     return HttpResponse("ok")
views.py

 

 

 

 

模板

1.模板语言
            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每周学习进度第十一周

Python自动化开发学习的第十二周----WEB基础(JavaScript+Dom)

2019--2020第十一周信息安全导论论总结20191301

2017-2018-2 20179305《网络攻防技术》第十一周作业

《信息安全专业导论》第十一周学习总结

20169217 2016-2017-2 《网络攻防实践》第十一周学习总结