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\r\n\r\n".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

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

 

posted @ 2020-07-11 23:06  ChungZhao  阅读(204)  评论(0编辑  收藏  举报