Python Django WEB框架

1 基本WEB框架

import socket

server = socket.socket()
ip_port = ('127.0.0.1',8000)
server.bind(ip_port)
server.listen()

while True:
    conn,addr = server.accept()
    recv_msg = conn.recv(1024)
    print(recv_msg)
    conn.send(b'My First WEB Server')
    conn.close()

在浏览器的URL输入框中输入:http://127.0.0.1:8000/,浏览器返回My First WEB Server

服务器端窗口输出:

GET / HTTP/1.1
Host: 127.0.0.1:8000
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4385.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,zh-CN;q=0.8,zh;q=0.7

2 WSGI

如何才能让服务器能够执行动态的内容?一般会分为两部分:服务器程序和应用程序。

  1. 应用程序则负责具体的逻辑处理。一般是通过 Python 或者 PHP 来处理,之后再把处理完的结果在提交到 HTTP 服务器程序

  2. HTTP服务器程序负责对socket服务器进行封装:将 HTTP 请求响应给客户端。

WSGI(Web Server Gateway Interface)就是一种规范,它定义了使用 Python 编写的 web 应用程序web服务器程序 之间的接口格式,实现 web 应用程序web服务器程序 间的解耦。wsgi 类似是 PythonHTTP 的一条通道。类似还有 CGI、FastCGI等。Apache、Nginx 等 HTTP服务器软件都是只负责处理 HTTP 的请求和响应,然后 Python、PHP 再通过类似 wsgi 这样的接口与之融合。

Python标准库提供的独立WSGI服务器叫 wsgiref ,Django开发环境用的就是这个模块来做服务器。

2.1 HTML文档模板

此模板试用于第二章所有实例。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>Title</title>
</head>
<body>
<h1>header1</h1>
<p>this is paragraph.</p>
<h1>{{ userinfo }}</h1>

<ul>
  {% for k,v in userinfo.items() %}
      <li>{{ k }}--{{ v }}</li>
  {% endfor %}
</ul>
</body>
</html>

2.2 WSGI-基本配置

from wsgiref.simple_server import make_server


def application(environ, start_response):
    """
    application 由wsgi服务器调用、函数对http请求与响应的封装
    :param environ: 返回浏览器http请求信息 (dist)
    :param start_response: WEB服务器响应客户端 (function)
    传给HTTP服务器程序时,格式应为byte类型,并加上"[]"
    :return:
    """
    print(environ)
    # 响应浏览器请求
    start_response('200 ok', [('Content-Type', 'text/html'), ('k1', 'v1'), ('k2', 'v2')])
    if environ['REQUEST_METHOD'] == 'GET' and environ['PATH_INFO'] == '/':
        with open('dynamicWEB.html', 'rb') as f:
            data = f.read()
        return [data]


# 启动服务器 | 这个服务器负责与 wsgi 接口的 application 函数对接数据
httpd = make_server('127.0.0.1', 8000, application)
# 监听请求
print('Serving HTTP on port 8000...')
httpd.serve_forever()

2.3 WSGI 动态WEB实现:结合Jinja2

结合Jinja2,用从数据库中查询数据去替换HTML文档中的对应内容,最后发送给浏览器完成渲染。

#!/usr/bin/env python
# -*- coding:UTF-8 -*-
# Author: Fan Carey
# Version 1.0
# Created time: 
# Description:

from wsgiref.simple_server import make_server
from jinja2 import Template
import pymysql


def user_data():
    """
    连接数据库,从数据库中查询数据并返回
    :return:
    """
    db_conn = pymysql.connect(
        host='127.0.0.1',
        port=3306,
        user='root',
        password='toor',
        database='jinja2',
        charset='utf8',
    )
    cursor = db_conn.cursor(pymysql.cursors.DictCursor)
    sql_cmd = 'select * from userinfo;'
    cursor.execute(sql_cmd)
    user_tmp_data = cursor.fetchone()
    print(user_tmp_data)
    db_conn.commit()
    cursor.close()
    db_conn.close()
    return user_tmp_data


def application(environ, start_response):
    """
    application 由wsgi服务器调用、函数对http请求与响应的封装
    :param environ: 返回浏览器http请求信息 (dist)
    :param start_response: WEB服务器响应客户端 (function)
    传给HTTP服务器程序时,格式应为byte类型,并加上"[]"
    :return:
    """
    # 响应浏览器请求
    start_response('200 ok', [('Content-Type', 'text/html'), ('k1', 'v1'), ('k2', 'v2')])
    user_dbdata = user_data()
    if environ['REQUEST_METHOD'] == 'GET' and environ['PATH_INFO'] == '/':
        with open('dynamicWEB.html', 'r', encoding='utf-8') as f:
            data = f.read()
        tmp = Template(data)
        data = tmp.render({'userinfo': user_dbdata}).encode('utf-8')
        return [data]


# 启动服务器 | 这个服务器负责与 wsgi 接口的 application 函数对接数据
httpd = make_server('127.0.0.1', 8000, application)
# 监听请求
print('Serving HTTP on port 8000...')
httpd.serve_forever()

mysql 数据库配置

CREATE DATABASE `jinja2` CHARACTER SET utf8;
use jinja2;
CREATE TABLE `userinfo` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` char(32) NOT NULL,
  `age` int NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

3 Django

3.1 Django框架

  • MVC框架

    MVC(Model View Controller):是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller),具有耦合性低、重用性高、生命周期成本低等优点。

  • MTV框架

    • Django的MTV框架的设计模式借鉴了MVC框架的思想,也是分成三部分,来降低各个部分之间的耦合性。

      1. Model(模型):负责业务对象与数据库的对象(ORM)
      2. Template(模版):负责如何把页面展示给用户
      3. View(视图):负责业务逻辑,并在适当的时候调用Model和Template
    • 响应流程如下:

      img
    • 除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应的Model和Template,MTV的响应模式如下所示:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oE7GilE1-1614902827236)(https://i.loli.net/2021/01/14/lI8JRP6kiUSX5ET.png)]

3.2 Django基本使用

以Windows环境为例

3.2.1 命令行模式下创建 Django 项目

1、安装Django:
    $ pip3 install django==1.11.9
    $ python -m django --version # 查看当前安装Django版本
   
2、创建一个Django项目
    $ django-admin startproject mysite   #创建了一个名为"mysite"的 Django 项目。
    
    注:如果提示找不到该命令,请检查计算机环境变量中是否将以下目录添加至 Path 变量中。
    	C:\Users\username\AppData\Local\Programs\Python\Python38\Scripts

3、创建了以下文件
mysite/		# 根目录名称对 Django 没有影响
├── manage.py	# 管理 Django 项目文件。通过它可以调用django shell和数据库,启动关闭项目与项目交互
└── mysite/		# 项目目录
    ├── __init__.py
    ├── settings.py		# 配置文件
    ├── urls.py		#  URL 声明
    ├── wsgi.py		# 运行在 WSGI 兼容的Web服务器上的入口

4、启动项目
	$ python manage.py runserver
    $ python manage.py runserver 127.0.0.1:8080
    	# 默认情况下,runserver 命令会将服务器设置为监听本机内部 IP 的 8000 端口。
	如果设置服务器的监听本地访问 8080 端口:
        $ python manage.py runserver 8080 
    如果设置服务器的监听所有访问 8080 端口:
        $ python manage.py runserver 0:8000

5、创建一个应用
$ python manage.py startapp polls

在项目的配置文件settings.py中添加一个polls的配置

INSTALL_APPS = [
	'polls', app名称
]

INSTALLED_APPS = [
    # 方法1
    'polls.apps.PollsConfig',
    # 方法2
    'polls',
]

3.2.2 使用 Pycharm 创建 Django 项目

  • 打开Pycharm,选择New Project,在弹出窗口配置如下:
image-20210114100717389
  • 运行新创建的项目

    在打开的项目界面上,点击Pycharm 左上角的运行按钮的左边,选择刚刚创建的项目名称 “djangoProject” ,再点运行,即可启动。

    或在Pycharm下面的终端输入:python manage.py runserver

3.3 Django 配置文件修订

setting.py 

1、template文件夹位置
	设置template的'DIRS' 的值如下。
TEMPLATES = [
    {
        'DIRS': [os.path.join(BASE_DIR, "template")],
    }
]

2、添加静态文件存放位置
STATIC_URL = '/static/'  # HTML中使用的静态文件夹前缀
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"), 
]

3、暂时禁用csrf中间件,方便表单提交测试。
MIDDLEWARE = [
    # 'django.middleware.csrf.CsrfViewMiddleware',
]


4 配置一个项目

4.1 urls.py

默认匹配顺序是从上到下,且只要匹配上,便不再继续向下查找。

url(r'^admin/', admin.site.urls)	# 第一个参数:匹配路径正则字符串,第二个参数:对应的视图函数

urlpatterns = [
    # 网站首页显示URL路径下,开头与结尾都为空才可以匹配。
    url(r'^$', views.home),
	# 无名分组
    url(r'^index/$', views.index),
    # 位置参数
    url(r'^articles/(\d{4})/(\d{1,2})/$', views.years_month_request),
    # 有名分组
    url(r'^articles/(?P<year>[0-9]{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/$', views.date_request),
    # 默认值
    url(r'^articles/(\d{2})/$', views.default_request),
    # 匹配任意
    url(r'', views.home),
]

4.2 views.py

对应urls.py所传回的参数。

# 无名分组
def index(request):
    print(request.method)
    if request.method == 'GET':
        print(request.GET)
        return render(request,'login.html')
    else:
        print(request.POST)
        username = request.POST.get('username')
        password = request.POST.get('password')
        print(username,password)
        if username== 'abname' and password=='abpass':
            return HttpResponse('get correct username and password')
        else:
            return HttpResponse('get wrong information!')
            
# 位置参数
def years_month_request(request,year,month):
    print('year-->: ',year)
    print('month-->: ',month)
    return HttpResponse(year+month)

# 有名分组
def date_request(request,day,month,year):
    print('year-->: ',year)
    print('month-->: ',month)
    print('day-->: ',day)
    return HttpResponse(year+month+day)

# 默认值
def default_request(request,year='2020',month='01'):
    return HttpResponse("special year='2020',month='01'")

4.3 login.html

对应 views.py 下 index()方法所调用的模板。

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>Title</title>
</head>
<body>
<h1>welcome to log in.</h1>
<p>here is login.html</p>
<form action="" method="post">
    <label for="username">username:
        <input type="text" name="username" placeholder="username">
    </label>
    <label for="password">password:
        <input type="password" name="password" placeholder="password">
    </label>
    <input type="submit" value="submit">
</form>
</body>
</html>
posted @ 2021-03-05 08:09  f_carey  阅读(4)  评论(0编辑  收藏  举报  来源