一、Django简介

Django简介

1、软件开发架构

"""
CS架构
BS架构
本质上来说,BS架构也是CS架构
"""

2、Web框架

  1. Web框架本质:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。

  2. HTTP协议

    # HTTP协议是一种网络协议
    
    # 网络协议
    """
        HTTP协议 			数据传输是明文
        HTTPS协议			数据传输是密文
        websocket协议		数据传输是密文
    """
    
    # HTTP协议的特性
    """
        1.基于请求响应
        2.基于TCP/IP作用于应用层之上的协议
        3.无状态
        4.短/无链接
    """
    
    # 数据格式
    """
        请求首行
        请求头
        
    
        请求体
    """
    
    # 响应状态码
    """
    	1XX
    	2XX		200
    	3XX
    	4XX		403 404
    	5XX		500
    """
    

3、手撸Web框架

# 你可以将web框架理解成服务端
import socket


server = socket.socket()  # TCP  三次握手四次挥手  osi七层
server.bind(('127.0.0.1',8080))  # IP协议 以太网协议 arp协议...
server.listen(5)  # 池 ...

"""
b'GET / HTTP/1.1

Host: 127.0.0.1:8082

Connection: keep-alive

Upgrade-Insecure-Requests: 1

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 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;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: zh-CN,zh;q=0.9

Cookie: csrftoken=KYJnVBLPpJxwt09TOmTXzpb5qkFJwHVxVGpi0NxEGIg4z5VUuazZ1O2RMwSisu14


'


"""
while True:
    conn, addr = server.accept()
    data = conn.recv(1024)
    # print(data)  # 二进制数据
    data = data.decode('utf-8')  # 字符串
    # 获取字符串中特定的内容       正则  如果字符串有规律也可以考虑用切割
    conn.send(b'HTTP/1.1 200 OK

')
    current_path = data.split(' ')[1]
    # print(current_path)
    if current_path == '/index':
        # conn.send(b'index heiheihei')
        with open(r'templates/01 myhtml.html', 'rb') as f:
            conn.send(f.read())
    elif current_path == '/login':
        conn.send(b'login')
    else:
        # 你直接忽略favicon.ico
        conn.send(b'hello web')
    conn.close()
  • 不足之处:
    • 代码重复(服务端代码所有人都要重复写)
    • 手动处理http格式的数据 并且只能拿到url后缀 其他数据获取繁琐(数据格式一样的处理代码大致也是一样的)
    • 并发问题没处理

4、借助于wsgiref模块撸Web

from wsgiref.simple_server import make_server
from urls import urls
from views import *


def run(env, response):
    """
    :param env:请求相关的所有数据
    :param response:响应相关的所有数据
    :return: 返回给浏览器的数据
    """
    # print(env)  # 大字典  wsgiref模块帮你处理好http格式的数据 封装成了字典让你更加方便的操作
    # 从env中取
    response('200 OK', [])  # 响应首行 响应头
    current_path = env.get('PATH_INFO')
    # if current_path == '/index':
    #     return [b'index']
    # elif current_path == '/login':
    #     return [b'login']
    # return [b'404 error']
    # 定义一个变量 存储匹配到的函数名
    func = None
    for url in urls:  # url (),()
        if current_path == url[0]:
            # 将url对应的函数名赋值给func
            func = url[1]
            break  # 匹配到一个之后 应该立刻结束for循环
    # 判断func是否有值
    if func:
        res = func(env)
    else:
        res = error(env)

    return [res.encode('utf-8')]


if __name__ == '__main__':
    server = make_server('127.0.0.1',8080,run)
    """
    会实时监听127.0.0.1:8080地址 只要有客户端来了
    都会交给run函数处理(加括号触发run函数的运行)
    
    flask启动源码
        make_server('127.0.0.1',8080,obj)
        __call__
    """
    server.serve_forever()  # 启动服务端
  • 重点

    """
    urls.py			路由与视图函数对应关系
    views.py		视图函数(后端的业务逻辑)
    manage.py		启动代码
    templats文件夹	  用来存放HTML
    """
    

5、动静态页面

  1. 静态页面

    • 页面上的数据是直接写死的,不会变化
  2. 动态页面

    • 页面上的数据是实时获取的
  3. 具体示例

    # 动态网页制作1
    # 主要方法是获取后端页面代码(字符串),替换字符串中的某些数据为我们后端写的代码,比如下面的时间
    import datetime
    def get_time(env):
        current_time = datetime.datetime.now().strftime('%Y-%m-%d %X')
        # 如何将后端获取到的数据"传递"给html文件?
        with open(r'templates/03 mytime.html','r',encoding='utf-8') as f:
            data = f.read()
            # data就是一堆字符串
        data = data.replace('dwadasdsadsadasdas',current_time)   # 在后端将html页面处理好之后再返回给前端
        return data
    
    
    # 动态页面制作2
    # 将一个字典传递给html文件 并且可以在文件上方便快捷的操作字典数据
    from jinja2 import Template
    def get_dict(env):
        user_dic = {'username':'jason','age':18,'hobby':'read'}
        with open(r'templates/04 get_dict.html','r',encoding='utf-8') as f:
            data = f.read()
        tmp = Template(data)
        res = tmp.render(user=user_dic)
        # 给get_dict.html传递了一个值 页面上通过变量名user就能够拿到user_dict
        return res
    
    # 后端获取数据库中数据展示到前端页面
    
    <body>
    
  4. 模板语法之jinja2模块

    # 模版语言
    # 可以简单的取值
    {{ user }}
    {{ user.get('username')}}
    {{ user.age }}
    {{ user['hobby'] }}
    
    # 也可以for循环创建table
    {% for user_dict in user_list %}
                            <tr>
                                <td>{{ user_dict.id}}</td>
                                <td>{{ user_dict.username}}</td>
                                <td>{{ user_dict.password}}</td>
                                <td>{{ user_dict.hobby}}</td>
                            </tr>
    {% endfor%}
    
    </body>
    

6、三大主流Web框架

"""
django
	特点:大而全 自带的功能特别特别特别的多 类似于航空母舰
	不足之处:
		有时候过于笨重

flask
	特点:小而精  自带的功能特别特别特别的少 类似于游骑兵
	第三方的模块特别特别特别的多,如果将flask第三方的模块加起来完全可以盖过django
	并且也越来越像django
	不足之处:
		比较依赖于第三方的开发者
		
tornado
	特点:异步非阻塞 支持高并发
		牛逼到甚至可以开发游戏服务器
	不足之处:
		暂时你不会
"""

"""
A:socket部分
B:路由与视图函数对应关系(路由匹配)
C:模版语法

django
	A用的是别人的		wsgiref模块
  B用的是自己的
  C用的是自己的(没有jinja2好用 但是也很方便)

flask
	A用的是别人的		werkzeug(内部还是wsgiref模块)
  B自己写的
  C用的别人的(jinja2)

tornado
	A,B,C都是自己写的
"""

7、启动一个Django项目

①、启动前的注意事项

  1. 计算机问题
    • 计算机名称不能有中文
    • 一个pycharm窗口只能开一个项目
    • 项目里面的所有文件尽量使用英文
    • python解释器尽量使用3.4~3.6之间的版本,(如果用高级版本的python可能会报错,点击最后一个报错信息,删除最后一个逗号即可)
  2. Django版本问题
    • 1.X、2.X用的比较多,由于3.X是最新发布的,优先不考虑
    • 目前使用的是1.11.11
  3. Django安装
    • 命令行输入:pip3 install django==1.11.11
    • 在pycharm里的setting中安装,注意切换python解释器
    • 检验安装是否成功:在命令行输入Django-admin

②、Django的基本操作(终端版)

  1. 创建Django项目

    • 到指定的盘符下面cmd输入:django-admin startproject mysite

    • 此时会创建一个mysite文件夹

      # 文件夹详情
      """
      - mysite
      	-- manage.py
      	-- mysite文件夹
      		--- __init__.py
      		--- setting.py
      		--- urls.py
      		--- wsgi.py
      """
      
  2. 情动Django项目

    • cmd切换到mysite文件夹下,输入:python manage.py runserver
  3. 创建应用

    • cmd到mysite文件架下面,输入:python manage.py startapp app01(app的名称应该见名知意)

③、Django基本操作(pycharm版)

  1. 创建项目:点击新建项目即可(注意python解释器)
  2. 启动:pycharm命令行或者命令行启动manage.py文件
  3. 创建app:pycharm命令行,或者点击tools,点击run manage.py task...提示创建
  4. 修改端口号:点击edit config

④、应用(APP)

  1. Django是一款专门开发app的web框架,这里的app不是手机上的app,而是功能的意思。一个app代表一类功能,一个Django框架就是一群app的集合体。

  2. 注意:每次创建完app后都要到settings里面注册

    # 找到项目下的settins.py
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',  # 全写
      	'app01',			 # 简写
    ]
    

⑤、主要文件介绍

# mysite(项目文件夹)
"""
- mysite(文件夹)
	-- settings.py(配置文件)
	-- urls.py(路由与视图层的对应关系)路由层
	-- wsgi.py(wsgiref模块 不考虑)
- manage.py(启动文件)
- db.splite3(自带的小型数据库,功能不是很完善还有很多bug)
- app01(文件夹)
	-- admin.py(Django后台管理)
	-- apps.py(注册使用)
	-- migrations.py(数据迁移记录)
	-- models.py(数据库相关的模型类 ORM)
	-- test.py(测试文件)
	-- views.py(视图函数)
"""

⑥、命令行创建和pycharm创建的区别

# 1 命令行创建不会自动有templatew文件夹 需要你自己手动创建而pycharm会自动帮你创建并且还会自动在配置文件中配置对应的路径
# pycharm创建
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'templates')
                 
]
# 命令行创建
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
    }
]
"""
也就意味着你在用命令创建django项目的时候不单单需要创建templates文件夹还需要去配置文件中配置路径
'DIRS': [os.path.join(BASE_DIR, 'templates')]
"""

⑦、Django小白必会三板斧

  1. HttpResponse

    • 在views.py文件中使用,返回字符串类型的数据

      return HttpResponse('字符串')
      
  2. render

    • 在views.py文件中使用,返回HTML文件

      return render(request,'login.html')
      
    • reder的传值方式

      def ab_render(request):
          user_info = {'username':'jason','age':18}
          # 第一种传值方式:传值更加精确,节省资源
          return (request,'login.html',{'data':user_info})
      	# 第二种传值方式:当需要传的值比较多的时候
          """locals会将所在的名称空间中所有的名字都传给HTML页面,包括request"""
          return (request,'login.html',locals())
      
  3. redirect

    • 重定向
    • 指定页面:return redirect(‘https://www.baidu.com’)
    • 拼接当前页面:return redirect(‘home’)

8、静态文件配置

①、前戏

  1. 引子:在写项目时我们默认把HTML文件放在template文件夹下,而网站使用的静态文件放在static文件夹下

  2. 静态文件:前端已经写好地直接调用的文件夹

    • 前端使用的框架
    • JS脚本
    • CSS样式
    • 图片
  3. static文件夹详情

    """
    - static
    	-- js
    	-- css
    	-- img
    	-- others(框架)
    """
    

②、如何配置

  1. 在setting中配置

    # static类似于访问静态文件的令牌
    STATIC_URL = '/static/'
    
    # 静态文件的文件路径,可以有多个
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR,'static'),
        os.path.join(BASE_DIR,'static1'),
        os.path.join(BASE_DIR,'static2'),
    ]
    
  2. 静态文件动态解析(在前端页面书写)

    {% load static %}
        <link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
    
  3. 补充

    • 在浏览器中输入url能够看到对应的资源,是因为后端提前开设了该url的资源接口。如果访问不到资源,说明后端没有开设该url的资源接口

    • form表单的action参数

      • 不写:默认朝当前所在的url提交数据
      • 全写:指名道姓朝哪个url提交数据
      • 只写后缀:/login/,朝后端login这个视图函数提交数据
    • 前期使用Django提交post请求时,需要在setting中注释一行代码

      MIDDLEWARE = [
          'django.middleware.security.SecurityMiddleware',
          'django.contrib.sessions.middleware.SessionMiddleware',
          'django.middleware.common.CommonMiddleware',
          # 'django.middleware.csrf.CsrfViewMiddleware',
         'django.contrib.auth.middleware.AuthenticationMiddleware',
          'django.contrib.messages.middleware.MessageMiddleware',
          'django.middleware.clickjacking.XFrameOptionsMiddleware',
      ]
      

9、request对象初识

  1. 对象初识

    • reques.method:返回请求方式,并且是全大写的字符串
    • request.POST:获取用户post请求提交的数据,不包含文件
      • request.POST.get():只获取列表最后一个元素
      • request.POST.getlist():直接获取列表中的全部元素
    • request.GET:获取用户提交的get请求数据
      • request.GET.get():只获取列表最后一个元素
      • request.GET.getlist():直接获取列表中的全部元素
  2. 具体示例

    request.method # 返回请求方式 并且是全大写的字符串形式  <class 'str'>
    request.POST  # 获取用户post请求提交的普通数据不包含文件
    	request.POST.get()  # 只获取列表最后一个元素
      request.POST.getlist()  # 直接将列表取出
    request.GET  # 获取用户提交的get请求数据
    	request.GET.get()  # 只获取列表最后一个元素
      request.GET.getlist()  # 直接将列表取出
    """
    get请求携带的数据是有大小限制的 大概好像只有4KB左右
    而post请求则没有限制
    """
      
    def login(request):
        # 返回一个登陆界面
        """
        get请求和post请求应该有不同的处理机制
        :param request: 请求相关的数据对象 里面有很多简易的方法
        :return:
        """
        # print(type(request.method))  # 返回请求方式 并且是全大写的字符串形式  <class 'str'>
        # if request.method == 'GET':
        #     print('来了 老弟')
        #     return render(request,'login.html')
        # elif request.method == 'POST':
        #     return HttpResponse("收到了 宝贝")
        
        if request.method == 'POST':
            return HttpResponse("收到了 宝贝")
        return render(request, 'login.html')
    

10、pycharm连接数据库(MySQL)

  1. pycharm中数据库位置
    • 右侧上方database
    • 左下方database
    • settings中的plugins插件搜索database安装
  2. 具体使用:和navigate里的一样操作

11、Django连接数据库

  1. 前戏:Django中的数据库默认是用sqlite3

  2. 具体配置

    • 在settings.py中配置

        	DATABASES = {
          'default': {
              'ENGINE': 'django.db.backends.mysql',
              'NAME': 'day60',
              'USER':'root',
              'PASSWORD':'admin123',
              'HOST':'127.0.0.1',
              'PORT':3306,
              'CHARSET':'utf8'
          }
      }
      
    • 代码声明

      # 在项目名的init.py或者任意应用名下的init.py文件中书写以下代码
      import pymysql
      pymysql.install_as_MySQLdb()
      

12、Django请求生命周期流程图

image-20210625194309685

原文地址:https://www.cnblogs.com/borntodie/p/14330580.html