zoukankan      html  css  js  c++  java
  • 初识 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),
    ]

      

  • 相关阅读:
    mysql索引
    mysql视图
    pymysql
    web前端基础
    【BZOJ2002】[HNOI2010] 弹飞绵羊(大力分块)
    【BZOJ2730】[HNOI2012] 矿场搭建(找割点)
    网络流(一)——最大流
    欧拉路与欧拉回路
    扫描线(一)——求矩形面积并
    【洛谷3396】哈希冲突(大力分块)
  • 原文地址:https://www.cnblogs.com/1624413646hxy/p/11160756.html
Copyright © 2011-2022 走看看