• 一、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

  • 相关阅读:
    javascript如何处理字符串中的u
    查看postgresql的日志show queries log in PostgreSQL?
    angular7 promiss
    解决echarts的叠堆折线图数据出现坐标和值对不上的问题
    微信小程序将图片数据流添加到image标签中
    深入理解flex布局的flex-grow、flex-shrink、flex-basis
    优先级:content –> width –> flex-basis (limted by max|min-width)
    ubuntu17.10 python3.6 install plugins for AI
    tensorflow import 没找到cudnn库问题解决
    ubuntu17.10 安装ssh
  • 原文地址:https://www.cnblogs.com/borntodie/p/14330580.html
Copyright © 2020-2023  润新知