初识 Django

啥是DNS

DNS是域名解析系统,当我们通过浏览器发送如“ baidu.com” 时会先发送给本地DNS,没有找到的话会再发送到根服务器,世界上一共有13台根服务器,

10台在美国,两台在欧洲,一台在日本。这不是重点,根服务器会拿到我们发的请求时,会解析后面的.com部分,发送信息给

管理.com的顶级服务器中去查找,再通过.com顶级服务器找到管理baidu.com的权威服务器,返回一个ip和端口给本地DNS,本地会记录下来IP地址并访问www.baidui.com。

DNS就是记录着域名和ip的对应关系

HTTP协议

http协议向服务器请求时使用的 由两个部分组成的,请求头和请求体,请求头和请求体用 分隔开,请求头中包含请求方式,方式选择上有两种,客户端不往服务器传数据可以使用,get请求,有数据传输的时候可以使用post请求。还包含请求的主机名,本次的连接状态,在http1.1版本下默认使用的是长链接的形式,最重要的是user-Agent 其中包含了我们请求的主要信息。

# b'GET / HTTP/1.1
  请求方式,请求页面和协议版本号 
# Host: 127.0.0.1:8001
 被请求的主机名
# Connection: keep-alive
   链接状态---本次长连接
# Cache-Control: max-age=0
  缓存失效
# Upgrade-Insecure-Requests: 1
 
# User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36

# Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3

# Referer: https://www.baidu.com/s?ie=UTF-8&wd=127.0.0.1%EF%BC%9A8001

# Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9

'

请求体就是我们输入的内容。

请求和相应是相对应的,所以服务器也会有响应头和响应体,最基础的要包含http和版本号,状态码,是200的话再来一个ok,讲究一点在指定一个字符编码。

(b'HTTP/1.1 200 ok
Content-Type: text/html;charset=utf8

'

在http协议下我们不指定端口时默认使用的是80端口,在https协议下默认的端口是443

相应的状态码:

2XX: 200 (ok)

3XX: 302 304

4XX: 404(not found) 403(forbidden 禁止访问)

5XX: 500 (服务端代码错误) 502 (网关错误 bad gateway)

Django前菜:手撸简易web框架

可以自己写出一个socket服务端,指定我们自己主机的ip和端口通过浏览器向服务器发起请求通信完成请求和回应,

原理是在服务端解析客户端,得到客户端发起请求的方式,请求的页面。

在服务器方面我们可以模拟Django中的路由系统建立字符串和函数的对应关系。做一个任务的分发,当客户端请求的页面在

我们所设定的列表中时,就调用向对应的函数,处理数据并返回处理结果给客户端。

def f1():
    return 'this is xxx'


def f2():
    return 'this is ooo'

def f3():
    pass

router = [
    ('/xxx',f1),
    ('/ooo',f2),
    ('/three',f3)
]

服务器主要逻辑,及部分实现的功能代码:

import datetime
import socket
import time
import pymysql
server = socket.socket()
server.bind(('127.0.0.1',8001))
server.listen(5)
def f1():
    return 'this is xxx'
def f2():
    return 'this is ooo'
def f3():
    pass
router = [
    ('/xxx',f1),
    ('/ooo',f2),
    ('/three',f3)
]
while True:
    print('监听8001端口')
    client,addr = server.accept()
    #接收到客户端发来的数据
    data = client.recv(1024)
    print(data)
    #j将接收到二进制数据转为字符串形式,进行切分找到我们想要的响应头中的内容
    res = str(data,encoding='utf-8')
    #想要的响应头部分内容通过打印在响应头的在切分所得列表的0号位
    request_list = res.split('
')[0]
    #再将取得的数据按空格切分
    frist_list = request_list.split(' ')

  ['GET', '/xxx', 'HTTP/1.1']# frist_list打印结果
client.send(b
'HTTP/1.1 200 ok Content-Type: text/html;charset=utf8 ') funcname = None for item in router: if frist_list[1] == item[0]: funcname = item[1] if funcname: res = funcname() client.send(bytes(res,encoding='utf-8')) else: client.send(bytes('404 not found',encoding='utf-8')) client.close()


客户端发来请求的打印结果:

#
b'GET / HTTP/1.1 # Host: 127.0.0.1:8001 # Connection: keep-alive # Cache-Control: max-age=0 # Upgrade-Insecure-Requests: 1 # User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36 # Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3 # Referer: https://www.baidu.com/s?ie=UTF-8&wd=127.0.0.1%EF%BC%9A8001 # Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 '





模板渲染

模板渲染可以自己定制规则,也可以使用第三方模块,

将数据库中的数据查找出后,可以结合html来形成渲染模板将结果融合在一起。

我们先将数据库中的数据通过列表套字典的形式取出,我们在我们想要渲染的html页面中,用一个占位符去先代替,

我们想要渲染进去的数据,再打开html文件后,读出数据后。我们将数据拼接成表格的形式,通过替换来将本来html文件中

的占位符替换掉这样html中的数据就是我们数据库的数据,并且数据是动态的。

import pymysql
    conn = pymysql.connect(host='127.0.0.1', user='root', password='123', db='db1', charset='utf8')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = "select id, name, depart_id from userinfo"
    cursor.execute(sql)
    res = cursor.fetchall()

    ### 模板渲染
    ### 需要将html代码和mysql结果融合
    res_list = []
    for user in res:
        res_str = "<tr><td>%s</td><td>%s</td><td>%s</td></tr>" % (user['id'], user['name'], user['depart_id'])
        res_list.append(res_str)
    s = "".join(res_list)

    fp = open('content.html', 'r', encoding='utf-8')
    data = fp.read()

    data = data.replace("@@content@@", s)

    return bytes(data, encoding='utf-8')

第三方模块渲染

导入第三方模块

 from jinja2 import Template

使用template去找到html文件中的占位符,将它替换成我们自己拼接好的数据。在html中去对数据进行取值遍历

在添加数据时要使用{{}}来包裹,对值进行循环遍历的时候要用{% for user in res%}进行包裹,对字典取值可以直接通过点的方法

来取值。

  import pymysql
    conn = pymysql.connect(host='127.0.0.1', user='root', password='123', db='db1', charset='utf8')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = "select id, name, depart_id from userinfo"
    cursor.execute(sql)
    users = cursor.fetchall()
    print(users)
    '''
    [
        {'id': 1, 'name': 'root1', 'depart_id': 1}, 
        {'id': 4, 'name': 'root2', 'depart_id': 3}, 
        {'id': 5, 'name': 'root3', 'depart_id': 5}, 
        {'id': 6, 'name': 'root4', 'depart_id': 1}, 
        {'id': 7, 'name': 'root5', 'depart_id': 3}
    ]
    '''

    ### 模板渲染
    ### pip3 install jinja2
    fp = open('content-jinji2.html', 'r', encoding='utf-8')
    data = fp.read()

    from jinja2 import Template
    template = Template(data)
    data = template.render(users = users)


    return bytes(data, encoding='utf-8')

安装Django
在cmd终端中安装方法:pip3 install Django==1.11.10

Django帮我们封装了,socket,我们不用自己去获取客户端的请求,

目录介绍:

mysite:
mysite:
settings.py : 用户自定义的各种配置
urls.py : 路由文件
wsgi.py : 启动socket服务端的 文件

mange.py: 管理文件 python mange.py 各种命令

创建完成以后我们要第一时间去配置一些静态文件路径,pycharm已经给我们配置好了动态文件路径

还要注释掉 MIDDLEWARE 中间的一条配置文件:#'django.middleware.csrf.CsrfViewMiddleware',

静态文件配置:

    STATIC_URL = '/static/'
                    STATICFILES_DIRS =  (
                        os.path.join(BASE_DIR, 'static'), (逗号不能少)
                    )

书写uri和函数的对应关系:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', login),
    url(r'^user_table/', user_table),
]

创建Django项目: 在pycharm中在新建项目中点击Django即可

函数是我们书写业务逻辑的地方。

案例:实现简单的登录:

import pymysql
from django.conf.urls import url
from django.contrib import admin
from django.http import HttpResponse
from django.shortcuts import render,HttpResponse,redirect
def py():
    conn = pymysql.connect(host='localhost', user='root', password='123', database='db2', charset='utf8')
    cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
    sql = 'select * from login'
    cursor.execute(sql)
    conn.commit()
    res = cursor.fetchall()
    return res

def login(request):
    if request.method == "GET":
        return render(request,'login.html')
    elif request.method == 'POST':
        name = request.POST.get('username')
        pwd = request.POST.get('password')
        res = py()
        for user in res:
            if user['name'] == name and user['pwd'] == pwd:
                return redirect('/user_table')
            else:

                return render(request, 'login.html',{
                    'info':'登录失败'
                })

def user_table(request):
    res = py()
    return render(request,'user_table.html',locals())

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', login),
    url(r'^user_table/', user_table),
]

  

原文地址:https://www.cnblogs.com/1624413646hxy/p/11160756.html