zoukankan      html  css  js  c++  java
  • WebFramework-Basis-1st

    周六,多云,记录生活分享点滴

    参考博客:https://www.cnblogs.com/yuanchenqi/articles/6083427.html

    推荐博客:https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/

    Django 1.1

    web框架

    框架 framework

    • 特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统

    • 简单地说,就是你用别人搭建好的舞台来做表演

    对于所有的Web应用,本质上是一个socket服务端;用户的浏览器是一个socket客户端。

    import socket
    ​
    def handle_request(client):
    ​
        buf = client.recv(1024)
        client.send("HTTP/1.1 200 OK
    
    ".encode("utf8"))
        client.send("<h1 style='color:red'>Hello, yuan</h1>".encode("utf8"))
    ​
    def main():
    ​
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.bind(('localhost',8001))
        sock.listen(5)
    ​
        while True:
            connection, address = sock.accept()
            handle_request(connection)
            connection.close()
    ​
    if __name__ == '__main__':
    ​
        main()

    最简单的Web应用:

    • 先把HTML用文件保存好,

    • 用一个现成的HTTP服务器软件,接收用户请求,

    • 从文件中读取HTML,返回

    如果要动态生成HTML,需要把上述步骤自己来实现:

    • 底层代码由专门的服务器软件实现,

    • 用Python专注于生成HTML文档

    • 需要统一的接口(WSGI:Web Server Gateway Interface),用Python编写Web业务

    -- -- -- -- -- -- -- -- -- -- web框架制作步骤 -- -- -- -- -- -- -- -- -- --

    step 1

    from wsgiref.simple_server import make_server
    ​
    ​
    def application(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        return [b'<h1>Hello, web!</h1>']
    ​
    ​
    httpd = make_server('', 8080, application)
    ​
    print('Serving HTTP on port 8000...')
    # 开始监听HTTP请求:
    httpd.serve_forever()

    注意:

    整个application()函数本身没有涉及到任何解析HTTP的部分,也就是说,底层代码不需要我们自己编写,
    我们只负责在更高层次上考虑如何响应请求就可以了。
    ​
    application()函数必须由WSGI服务器来调用。有很多符合WSGI规范的服务器,我们可以挑选一个来用。
    ​
    Python内置了一个WSGI服务器,这个模块叫wsgiref    
        
    application()函数就是符合WSGI标准的一个HTTP处理函数,它接收两个参数:
    ​
            //environ:一个包含所有HTTP请求信息的dict对象;
            
            //start_response:一个发送HTTP响应的函数。
    ​
    在application()函数中,调用:
    ​
    start_response('200 OK', [('Content-Type', 'text/html')])
    ​
    就发送了HTTP响应的Header,注意Header只能发送一次,也就是只能调用一次start_response()函数。
    start_response()函数接收两个参数,一个是HTTP响应码,一个是一组list表示的HTTP Header,每
    个Header用一个包含两个str的tuple表示。
    ​
    通常情况下,都应该把Content-Type头发送给浏览器。其他很多常用的HTTP Header也应该发送。
    ​
    然后,函数的返回值b'<h1>Hello, web!</h1>'将作为HTTP响应的Body发送给浏览器。
    ​
    有了WSGI,我们关心的就是如何从environ这个dict对象拿到HTTP请求信息,然后构造HTML,
    通过start_response()发送Header,最后返回Body。

    step 2

    print(environ['PATH_INFO'])
        path=environ['PATH_INFO']
        start_response('200 OK', [('Content-Type', 'text/html')])
        f1=open("index1.html","rb")
        data1=f1.read()
        f2=open("index2.html","rb")
        data2=f2.read()
    ​
        if path=="/yuan":
            return [data1]
        elif path=="/alex":
            return [data2]
        else:
            return ["<h1>404</h1>".encode('utf8')]

    step 3

    from wsgiref.simple_server import make_server
    ​
    def f1():
        f1=open("index1.html","rb")
        data1=f1.read()
        return [data1]
    ​
    def f2():
        f2=open("index2.html","rb")
        data2=f2.read()
        return [data2]
    ​
    def application(environ, start_response):
    ​
        print(environ['PATH_INFO'])
        path=environ['PATH_INFO']
        start_response('200 OK', [('Content-Type', 'text/html')])
    ​
    ​
        if path=="/yuan":
            return f1()
    ​
        elif path=="/alex":
            return f2()
    ​
        else:
            return ["<h1>404</h1>".encode("utf8")]
    ​
    ​
    httpd = make_server('', 8502, application)
    ​
    print('Serving HTTP on port 8084...')
    ​
    # 开始监听HTTP请求:
    httpd.serve_forever()

    step 4

    from wsgiref.simple_server import make_server
    ​
    ​
    def f1(req):
        print(req)
        print(req["QUERY_STRING"])
    ​
        f1=open("index1.html","rb")
        data1=f1.read()
        return [data1]
    ​
    def f2(req):
    ​
        f2=open("index2.html","rb")
        data2=f2.read()
        return [data2]
    ​
    import time
    ​
    def f3(req):        #模版以及数据库
    ​
        f3=open("index3.html","rb")
        data3=f3.read()
        times=time.strftime("%Y-%m-%d %X", time.localtime())
        data3=str(data3,"utf8").replace("!time!",str(times))
    ​
    ​
        return [data3.encode("utf8")]
    ​
    ​
    def routers():
    ​
        urlpatterns = (
            ('/yuan',f1),
            ('/alex',f2),
            ("/cur_time",f3)
        )
        return urlpatterns
    ​
    ​
    def application(environ, start_response):
    ​
        print(environ['PATH_INFO'])
        path=environ['PATH_INFO']
        start_response('200 OK', [('Content-Type', 'text/html')])
    ​
    ​
        urlpatterns = routers()
        func = None
        for item in urlpatterns:
            if item[0] == path:
                func = item[1]
                break
        if func:
            return func(environ)
        else:
            return ["<h1>404</h1>".encode("utf8")]
    ​
    httpd = make_server('', 8518, application)
    ​
    print('Serving HTTP on port 8084...')
    ​
    # 开始监听HTTP请求:
    ​
    httpd.serve_forever()

     

    MVC和MTV模式

    MVC模式:

    将web应用分为

    • 模型(M):模型负责业务对象与数据库的对象(ORM)

    • 控制器(C):控制器(C)接受用户的输入调用模型和视图完成用户的请求

    • 视图(V):视图负责与用户的交互(页面)

    三层之间以一种插件形式,松耦合的方式连接在一起。img

    Django的MTV模式也是各组件之间为了保持松耦合关系,在定义上有点不同

    Django的MTV分别代表:

    • Model(模型):负责业务对象与数据库的对象(ORM)

    • Template(模版):负责如何把页面展示给用户

    • View(视图):负责业务逻辑,并在适当的时候调用Model和Template

    补充:Django还有一个url分发器:作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

     

    django的流程和命令行工具

    详情参考:https://www.cnblogs.com/wj-1314/p/9406275.html

    django实现流程

        # 安装:pip3 install django
           添加环境变量
    
        # 1  创建project
           django-admin startproject mysite
    
           ---mysite
              ---settings.py
              ---url.py
              ---wsgi.py
    
           ---- manage.py(启动文件)  
    
        # 2  创建APP       
           python mannage.py startapp  app01
    
        # 3  settings配置
        
           TEMPLATES
    
           STATICFILES_DIRS=(
                os.path.join(BASE_DIR,"statics"),
           )
    
           STATIC_URL = '/static/' 
           #  我们只能用 STATIC_URL,但STATIC_URL会按着你的STATICFILES_DIRS去找
        
        # 4  根据需求设计代码
           url.py
           view.py
    
        # 5  使用模版
           render(req,"index.html")   
    
        # 6  启动项目
           python manage.py runserver  127.0.0.1:8090
    
        # 7  连接数据库,操作数据
           model.py

    django的命令行工具

    • django-admin.py 是Django的一个用于管理任务的命令行工具,

    • manage.py是对django-admin.py的简单包装,每一个Django Project里都会有一个mannage.py

    1.创建一个django工程

    django-admin startproject mysite

    当前目录下会生成一个 mysite的工程,目录结构如下:

    img

    • manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库等。

    • settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。

    • urls.py ----- 负责把URL模式映射到应用程序。

    2.在mysite目录下创建app应用

    python manage.py startapp blog

    img

    3.启动django项目

    python manage.py runserver 8080 # ip:端口,默认本地ip

    当我们访问:http://127.0.0.1:8080/ 时就可以看到:

    img

    4.生成同步数据库的脚本

    python manage.py makemigrations  

    同步数据库: python manage.py migrate

    注意:在开发过程中,数据库同步误操作之后,难免会遇到后面不能同步成功的情况,解决这个问题的一个简单粗暴方法是把migrations目录下的脚本(除__init__.py之外)全部删掉,再把数据库删掉之后创建一个新的数据库,数据库同步操作再重新做一遍。

    5.访问指定网址

    当我们访问http://127.0.0.1:8080/admin/时,会出现

    所以我们需要为进入这个项目的后台创建超级管理员:python manage.py createsuperuser设置好用户名和密码后便可登录

    6.清空数据库

    python manage.py flush

    7.查询某个命令的详细信息

    django-admin.py  help startapp

    admin 是Django 自带的一个后台数据库管理系统。

    8.启动交互界面

    python manage.py shell

    这个命令和直接运行 python 进入 shell 的区别是:你可以在这个 shell 里面调用当前项目的 models.py 中的 API,对于操作数据,还有一些小测试非常方便。

    9.查看详细列表

    终端上输入以下命令,可以看到详细的列表,在忘记子名称的时候特别有用

    python manage.py

    实例练习1-提交数据并展示

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>创建个人信息</h1><form action="/userInfor/" method="post"><p>姓名<input type="text" name="username"></p>
        <p>性别<input type="text" name="sex"></p>
        <p>邮箱<input type="text" name="email"></p>
        <p><input type="submit" value="submit"></p></form><hr><h1>信息展示</h1><table border="1"><tr>
            <td>姓名</td>
            <td>性别</td>
            <td>邮箱</td>
        </tr>
        {% for i in info_list %}
    ​
            <tr>
                <td>{{ i.username }}</td>
                <td>{{ i.sex }}</td>
                <td>{{ i.email }}</td>
            </tr>
    ​
        {% endfor %}
    ​
    </table></body>
    </html>
    ​
    ​
    -----------------------url.py---------------------------------------
    url(r'^userInfor/', views.userInfor)
    ​
    -----------------------views.py--------------------------------------
    ​
    info_list=[]
    ​
    def userInfor(req):
    ​
        if req.method=="POST":
            username=req.POST.get("username",None)
            sex=req.POST.get("sex",None)
            email=req.POST.get("email",None)
    ​
            info={"username":username,"sex":sex,"email":email}
            info_list.append(info)
    ​
        return render(req,"userInfor.html",{"info_list":info_list})

    实例练习2-提交数据并展示(数据库)

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <h1>创建个人信息</h1><form action="/userInfor/" method="post"><p>姓名<input type="text" name="username"></p>
        <p>性别<input type="text" name="sex"></p>
        <p>邮箱<input type="text" name="email"></p>
        <p><input type="submit" value="submit"></p></form><hr><h1>信息展示</h1><table border="1"><tr>
            <td>姓名</td>
            <td>性别</td>
            <td>邮箱</td>
        </tr>
        {% for i in info_list %}
    ​
            <tr>
                <td>{{ i.username }}</td>
                <td>{{ i.sex }}</td>
                <td>{{ i.email }}</td>
            </tr>
    ​
        {% endfor %}
    ​
    </table></body>
    </html>
    ​
    ​
    ----------------------------------------------models.py
    from django.db import models
    ​
    # Create your models here.
    ​
    ​
    class UserInfor(models.Model):
    ​
        username=models.CharField(max_length=64)
        sex=models.CharField(max_length=64)
        email=models.CharField(max_length=64)
    ​
    ----------------------------------------------views.py
    ​
    from django.shortcuts import render
    ​
    from app01 import models
    # Create your views here.
    ​
    ​
    def userInfor(req):
    ​
        if req.method=="POST":
            u=req.POST.get("username",None)
            s=req.POST.get("sex",None)
            e=req.POST.get("email",None)
    ​
    ​
           #---------表中插入数据方式一
                # info={"username":u,"sex":e,"email":e}
                # models.UserInfor.objects.create(**info)
    ​
           #---------表中插入数据方式二
            models.UserInfor.objects.create(
                username=u,
                sex=s,
                email=e
            )
    ​
            info_list=models.UserInfor.objects.all()
    ​
            return render(req,"userInfor.html",{"info_list":info_list})
    ​
        return render(req,"userInfor.html")

     

    Setting文件配置

    参考博客:https://www.cnblogs.com/5poi/p/6649101.html

    方法一

    静态文件在单独的app下:如 /app01/static/app01/JS/jquery-2.1.4.min.js

    (其中蓝色app01目录为必须,但可改其他名字,static文件夹也可改其他名字)

    # index.html<br>{% load static %}
    <script src="{% static 'app01/JS/jquery-2.1.4.min.js' %}"></script>

    setting文件设置: (其中app01为项目名字,static为保存静态文件的文件夹。)

    STATIC_URL = '/whattttt/'   # 前端使用前缀
     
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR,'app01','static'),
    )

    方法二(同上述setting配置)

    # index.html<br><script src="/whattttt/app01/JS/jquery-2.1.4.min.js"></script>

    方法三(使用别名的形式)

    # index.html<br>{% load static %}
    <script src="{% static 'biemin/JS/jquery-2.1.4.min.js' %}"></script>
         
    <script src="/whattttt/biemin/JS/jquery-2.1.4.min.js"></script>

    setting文件设置

    STATIC_URL = '/whattttt/'
     
    STATICFILES_DIRS = (
        ('biemin',os.path.join(BASE_DIR,'app01','static','app01')),
    )

    补充:

    如果不想每次在模版中加载静态文件都使用 {% load static%}

    可以在settings.py中的 TEMPLATES/OPTIONS添加'builtins':['django.templatetags.static']

    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',
          ],
          #添加在这个位置
          'builtins' : [
            'django.templatetags.static'
          ],
        },
      },
    ]

    补充:pycharm创建django项目

    主要总结一下在pycharm中进行django的创建遇到的问题

    对于django的安装和pipenv虚拟环境的设置可参考:https://www.zmrenwu.com/courses/hellodjango-blog-tutorial/materials/59/

    1.如果选择pipenv虚拟环境下创建django项目时,情况如下图

    2.然后进行创建中

    3.当在运行过程中如果出现这下图类似的错误

    4.可以尝试以下建议(https://pypi.tuna.tsinghua.edu.cn/simple

    5.修改完成后

    6.再次重新创建django,现在无法打开,静静等待最下面的蓝色字母运行完成(我的电脑需要运行一两分钟,有的是秒建,不知道什么原因)

    7.然后就可以正常运行django了

    8.总结

    需要修改文件夹下Pipfile文件中sours下的url,修改为 https://pypi.tuna.tsinghua.edu.cn/simple

    在此非常感谢群里的小伙伴提供的帮助,折腾了很久,终于可以继续学习了

  • 相关阅读:
    模块二:操作系统windows 7 的使用
    茶卡盐湖
    css元素居中指南
    新的CMS套站
    写响应式页面
    积累
    jquery方法整理
    积累 做网站添加的 所有动态效果
    产品中心有二级三级栏目。
    aspcms
  • 原文地址:https://www.cnblogs.com/chungzhao/p/13274009.html
Copyright © 2011-2022 走看看