django

一、Django简介

1、内容回顾
python基础语法
网络编程
并发编程
前端(HTML、css、js)
数据库(mysql)

2、今日概要
1、了解web应用程序的本质
2、Django简介、简单使用

3、今日详细(***)
1、web应用程序
2、http协议(尾生抱柱)
url:统一资源定位符
https 😕/ www.baidu.com /s ?wd=%E6%B3%A2

协议	分隔符		域名          路径		参数a=1&b=2 #
3、DIYWEB 框架
	form表单注意事项:
		1、active:服务器地址
		2、method:提交方式。默认GET,写错也是get
		3、input一定一定一定要写name属性
		4、submit按钮
4、Django
	库---小而精
	框架---大而全
	MVC模型
		M: model
		V:view(模板文件)
		C:URL与视图函数相关
	MTV模型
		
	Django版本问题(***面试时)
	
	1、Django下载
		命令行:
			
			pip install django 默认最新版本
			pip install django==1.11.20
			pip install django==1.11.20 -i https://pypi.doubanio.com/simple
			pip install -r requirements.txt -i https://pypi.doubanio.com/simple (批量安装)
		pycharm:
			自己体会
		
	2、创建第一个Django项目(你的第一次)
		命令行模式:
			django-admin startproject 项目名称
		pycharm:
			自己体会
	3、app相关
		1、创建app
			命令行模式:(当前命令行的路径,要跟manage.py同级)
				python manage.py startapp app名称
			pycharm:
				创建时指定。
	4、启动Django项目
		1、命令行模式:
			python manage.py runserver     # 默认 127.0.0.1:8000
			python manage.py runserver 80  # 127.0.0.1:80
			python manage.py runserver ip地址:端口  # IP地址:端口
		pycharm:
			自己体会
	5、简单示例:
		1、打开urls文件,配置URL与视图对应关系。
		2、打开app01/views.py ,写视图函数timer。
		3、在templates下创建模板文件timer.html {{ time }}
		4、视图timer视图函数,return时,加参数(字典, key必须要跟模板里对应)。

4、今日作业
1、Django下载
2、创建项目
3、创建app
4、urls.py
5、视图app01/views
6、templates下创建模板文件
7、视图return render,字符串(HttpResponse)

内容回顾

#### 1. HTTP协议
  1. tcp/IP协议

  2. HTTP特性:

    1. 无连接

    2. 请求--响应模式

    3. 请求格式

      1552441830432

  3. 响应格式

    1552441935666

    1. Django相关

      1. Django下载

        1. 命令行:

          pip install django==1.11.20 # 指定版本号

          pip install django==1.11.20 -i 豆瓣源

        2. pycharm

          1. 打开file
          2. settings
          3. project
          4. 点击+号
          5. input输入名称
          6. 不需要指定版本(直接install)
          7. 在右侧S开头选择对应版本,安装即可。
      2. 创建项目(第一次)

        1. 命令行模式

          django-admin startproject 项目名称

        2. pycharm

          1. 打开file
          2. new project 选择django
          3. 在顶部选择项目路径以及,项目名称
          4. 选择解释器
          5. app应用名称
          6. create创建
      3. 创建app

        1. 命令行模式(manage.py 同级目录)

          python manage.py startapp app名称

        2. tools---> Run manage.py Task ----直接输入命令即可

      4. 启动项目

        1. 命令行模式

          python manage.py runserver # 127.0.0.1:8000

          python manage.py runserver 8888 # 127.0.0.1:8888

          python manage.py runserver 192.168.1.2:8001 # 192.168.1.2:8001

        2. pycharm

          1. 找到项目select
          2. 点击edit
          3. host和port---->ok
          4. 绿色右三角按钮

      static配置注意:

      1552444757773

二、路由、视图、模板层

今日概要

  1. 路由层
  2. 视图层
  3. 模板层

今日详细

  1. 路由的简单使用

    urlpatterns = [
        path('admin/', admin.site.urls),
        path('login/', views.login),
        url(r'^articles/2003/$', views.article_2003),
        url(r'^articles/[0-9]{4}/$', views.article_year),
    
    ]
    
    1. 无名分组(按位置传参)

      url(r'^articles/([0-9]{4})/$', views.article_year),
      
    2. 有名分组(按关键字传参)

      1. 简单使用

        url(r'^articles/(?P<year>[0-9]{4})/$', views.article_year),
        

        注意事项:

        • 视图函数的形参,必须要跟有名分组的名称,同名,(顺序没有关系)
        • URL有几个分组,就必须要接收几个参数。
    3. 路由分发

      1552447556468

      1. 简单使用

        1. 项目最顶级的URL配置

          from django.conf.urls import url  # 运用django1版本的URL
          from django.urls import path, re_path, include
          urlpatterns = [
              url(r'^app01/', include("app01.urls")),
              url(r'^app02/', include("app02.urls"))
          
          ]
          
        2. 每个APP应用里面新建urls.py文件

          from django.conf.urls import url
          from app01 import views
          
          urlpatterns = [
              url(r'^login/$', views.login)
          ]
          

          注意事项:

          1. 项目顶级URL,结尾不要加$;
          2. include参数字符串路径,必须要写正确。

​ URL、path、re_path区别:

  1. URL

    1. 自己定制匹配规则
      2. path
      1. 自动带开头和结尾匹配规则
      2. include,自动去掉后面的$,进行URL拼接
  2. re_path

    1. 等同于django1版本的URL。
      1552450588380
  3. 视图层

    1. request对象

      1. 属性

        1. request.GET # 获取以GET请求方式,提交数据一个类似字典(QueryDict)

          request.GET.get("key") # 推荐写法

          request.GET.getlist("key") # 返回一个多值的列表

          request.GET["key"] # 不推荐,会报错

        2. request.POST # 获取以POST请求方式,提交数据一个类似字典(QueryDict)

          request.POST.get("key") # 推荐写法

          request.POST.getlist("key") # 返回一个多值的列表

          request.POST["key"] # 不推荐,会报错

        3. request.body # 请求体相关内容,原生的字节

        4. request.path # 获取URL路径,没有IP和端口

        5. request.method # 获取请求方式,大写

      2. 方法:

        1. get_full_path() # 获取URL的完整路径。
        2. is_ajax() # 返回布尔值,判断当前请求是否是ajax。
    2. HTTPResponse对象

      1. HttpResponse("想要显示的内容")

      2. render(request, "模板名称", [ 可选参数])

      3. redirect("要跳转的URL地址")

        1552462093711

  4. 模板层

    1. 变量

      语法:{{ name }}

    2. 过滤器

      {{obj|filter__name:param}}

      1. default

        设置默认值,两个参数,

      2. length

        获取长度, 只需一个参数|前

      3. filesizeformat

        格式化文件尺寸,只需一个参数|前

      4. date:"Y-m-d"

        格式化是日期。一个参数

      5. truncatechars

        截取字符串,两个参数,后面截取长度。

      6. safe

    1552465473058

    1. 标签

      1. for标签

        遍历每一个元素,展示数据

      2. if标签

        判断,从而影响,页面展示效果

      3. with标签

        定义一个中间变量

      4. csrf_token标签

        用于跨站请求伪造保护

    1552468802722

    1. 自定制过滤器和标签

      1. 在settings中的INSTALLED_APPS配置当前app,不然django无法找到自定义的simple_tag.

      2. 在app中创建templatetags模块(模块名只能是templatetags)

      3. 创建任意 .py 文件

      4. 在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py

      5. 如何使用

              
        {% load my_tags %}
        
        {{ li.0|filter_multi:li.1 }}
        
        {% simple_tag_multi li.0 li.1 v3=li.2 %}
        
        <p>{% my_input 3 "aaa" %}</p>
        

        注意:filter可以用在if等语句后,simple_tag不可以

今日作业

​ 运用今天所学的知识点,完成书籍展示页面(运用bootstrap的表格展示)

  数据见博客。

day46

一、内容回顾

1、路由层

1. 简单使用

```
    from django.conf.urls import url
    
    path('login/', views.login),
    url(r'^login/$', views.login),  # django1.X
    re_path(r'^login/$', views.login),
```
  1. 无名分组

    re_path(r'^articles/([0-9]{4})/$', views.year_archive),
    

    注意:

    1. 视图函数,必须要多接收一个参数。形参名称没有要求
    
  2. 有名分组

    re_path(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive),
    

    注意:

    视图函数的形参,必须要跟命名名称一致。(关键字传参)

  3. 路由分发

    from django.urls import path, re_path, include
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('app01/', include("app01.urls")),
    ]
    

2. 视图层

  1. request请求对象
   1. 属性
           1. GET
           2. POST
           3. body
           4. path
           5. method
   2. 方法
           1. get_full_path()  # 获取完整的路径,?后面的参数
           2. is_ajax()  # 返回布尔值,判断当前请求是否是Ajax。
  2. HttpResponse响应对象
   1. HttpResponse()  # 返回括号里的字符串
   2. render(request, "模板名称",[{'key':"val"},])
   3. redirect("要跳转的url地址")

3. 模板层

  1. 变量

    {{ name }}

  2. 过滤器

    1. lenght
    2. default
    3. filesizeformat
    4. date
    5. truncatechars
    6. safe(mark_safe.python使用)
  3. 标签

    1. for
    2. if
    3. csrf_token # 跨站请求伪造保护
  4. 自定制过滤器和标签

    1. 注册app

    2. 创建templatetags

    3. 创建XXX.py文件。

      from django import template
      from django.utils.safestring import mark_safe
       
      register = template.Library()   #register的名字是固定的,不可改变
      
    4. 在模板里加载

    ```html\
    {% load my_tags %} 
    ```
    
     5. 使用
    
    ```html
    -------------------------------.html
    {% load xxx %}  
          
    # num=12
    {{ num|filter_multi:2 }} #24
     
    {{ num|filter_multi:"[22,333,4444]" }}
     
    {% simple_tag_multi 2 5 %}  参数不限,但不能放在if for语句中
    {% simple_tag_multi num 5 %}
    ```
    

三、反向解析、名称空间、ORM及单表操作

二、今日概要

  1. url反向解析
  2. 名称空间
  3. orm简介
  4. orm单表操作

三、 今日详细

  1. url反向解析

    1. url定义name属性。注意:在当前app下name值唯一。

    2. 在视图里反向解析

      from django.urls import reverse
      
      url = reverse(name)
      # 位置传参(无名分组)
      url = reverse(name, args=(1,))
      # 关键字传参(有名分组)
      url = reverse(name, kwargs={key:val})
      
    3. 在模板里反向解析

    ```html
    {% url 'name' %}
    
    # 位置传参(无名分组)
    {% url 'name' arg1 arg2 ... %}
    
    # 关键字传参(有名分组)
    {% url 'name' key1=val1 key2=val2 ... %}
    ```
    
  2. 名称空间

    1. 定义时,要注意django1和django2的区别。
    path('app01/', include("app01.urls", namespace="app01")), # 这种写法使用django1.X
        path('app01/', include(("app01.urls", "app01"))),
        path('app02/', include(("app02.urls", "app02"), namespace="app02")),
    
    1. 反向解析在视图
    print(reverse("app01:login"))
    print(reverse("app02:login"))
    
    1. 模板里反向解析
    <form action="{% url 'app01:login' %}" method="post">
    <form action="{% url 'app02:login' %}" method="post">
    

    流程:

![1552530866731](../课上截图/1552530866731.png)
  1. ORM简介

    1. ORM流程

      1552531739143

    2. 理解orm与数据库的对应关系

      img

1552532694575

  1. django使用mysql数据的流程(ORM,只能操作数据表)

    1. 创建数据库

      create database 数据库名称 default charset=utf8;
      
    2. 在settings配置数据库

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',  # 注意改为
            'NAME': "数据库名称",
            'HOST': "127.0.0.1",
            'PORT': 3306,
            'USER': '用户名',
            'PASSWORD': "密码",
        }
    }
    
    3. 跟settings同级的init.py 配置
    
    import pymysql
    pymysql.install_as_MySQLdb()
    
    1. 在app下models.py 里写模型类

      class Book(models.Model):
          nid = models.AutoField(primary_key=True)
          title = models.CharField(max_length=32)
          price = models.DecimalField(max_digits=5, decimal_places=2)
          publish = models.CharField(max_length=64)
          pub_date = models.DateField()
      
    2. 在命令行,执行命令

      python manage.py makemigrations   # 把models变更记录记录下来。注意:此时,数据还没数据。
      python manage.py migrate  # 将数据导入到数据。同步。
      
  2. 单表操作(book)

    1. 新增数据操作

      1. 实例化对象方式

        book = models.Book(title="挤奶龙爪手", price=200, publish="华山出版社", pub_date="2019-2-22")
        book.save()  # 一定save,才能同步到数据库。
        
      2. objects管理对象

        book = models.Book.objects.create(title="葵花宝典", price=280, publish="明教出版社", pub_date="2018-1-17")
        
    2. 查询数据操作

      1. 返回QuerySet,类似列表

      2. all方法

      3. filter方法 (多个参数时,关系为and)

      4. exclude方法 (结果跟filter相反)

      5. order_by方法(默认是升序,降序在字段前加“-”)

      6. reverse方法 反转

      7. values 方法。类似列表。里面是类似字典。

      8. values_list方法 。类似列表。里面是元组。

      9. 返回对象。

      10. get方法

        1. 有多个值时,会报错。
        2. 没有匹配上的值时,会报错。
      11. first 方法

        1. 返回,有条件的。第一个插入的值
      12. last方法

        1. 返回,有条件的。最后一个插入的值
      13. 返回数据类型

      14. count方法 int

      15. exists方法 判断是否有值, 有值为True,反之。

四、今日作业

完成图书管理系统对图书的增删改查(建议使用bootstrap样式美化)

一、内容回顾

#### 1. URL反向解析

path('login/', views.login, name="login"),
  1. 视图中使用

    from django.urls import reverse
    
    url = reverse("login")
    
    1. 模板中使用
    {% url 'login' %}
    

    好处:便于扩展,当你的url发生改变的时候,通过反向解析的话,直接能获取最新的URL,不用自己手动修改。

  2. 名称空间

​ 背景:

​ 多个app时,下面有同名的name时,可以通过指定名称空间。来定位到,具体URL。

​ django1与django2的区别:

​ django1

url('^app01/', include("app01.urls", namespace="app01")),

​ django2

path('app01/', include(("app01.urls", "app01"))),
path('app02/', include(("app02.urls", "app02"), namespace="app02")),
  1. 视图中使用

    url = reverse("app01:login")  # login是app01下的
    
    1. 模板中使用
    {% url 'app01:login' %}
    
  2. ORM简介

  3. 概念

    对象关系映射(Object Relational Mapping,简称ORM)

  4. 优点:

    1. 写python代码,实现对数据表的相关操作。提高开发效率;
    2. 平滑切换数据库。
  5. 缺点:

    1. python代码,转换SQL需要时间,效率相对会有影响;
    2. SQL能力下降;
  6. django如何使用mysql数据库

    1. 手动创建数据库

      create database 库名 default charset=utf8;
      
      
    2. settings里配置

      DATABASES = {
          'default':{
              'ENGINE': 'django.db.backends.mysql',  # 引擎
              'HOST': '127.0.0.1',  # 数据库所在ip
              'PORT': 3306,  # 端口
              'NAME': '数据库名',  # 
              'USER': '用户名',
              'PASSWORD': '',  # 密码为空时,空字符串
          }
      }
      
      
    3. 配置init(settings同级的init文件)

      import pymysql
      pymysql.install_as_MySQLdb()
      
      
    4. 在models里定义模型类

      from django.db import models
      
      
      class Book(models.Model):
          title = models.CharField(max_length=32)
          ...
      
      
    5. 命令行输入命令

      python manage.py makemigrations  # 记录models变更记录下来
      python manage.py migrate  # 同步到数据库
      
      
  7. 单表操作

    1. 新增

      1. 方式一:

        book = models.Book(title="xxids", price=234,...)
        book.save()  # 同步到数据库
        
        
        
      2. 方式二:(objects管理对象)

        book = models.Book.objects.create(title="xxids", price=234,...)
        
        
    2. 查询

      1. QuerySet类似列表
        1. all 返回所有数据,对象
        2. filter 返回过滤满足条件的 对象列表。
        3. order_by 默认是升序,降序-
        4. values 类似字典。
        5. reverse 反转
        6. distinct 去重
        7. values_list 类似元组
        8. exclude 跟filter相反
      2. 返回对象
        1. get方法 (多个结果和没有结果会报错,有且只能有一个才行)
        2. first方法 获取最开始的一个
        3. last 方法 获取最后一个。
      3. 返回数据类型
        1. exists 返回值布尔值。判断是否有数据。
        2. count 返回int 计数。

四、ORM模糊查询、单表操作补充

二、今日概要

  1. 模糊查询
  2. 单表删除
  3. 单表修改
  4. 作业讲解

三、今日详细

#### 1. 模糊查询

  1. 编辑操作

  2. 新增的流程

    1552617211012

    1. 编辑流程

    1552617443761

  3. 单表编辑操作(代码见前一天的orm_danbiao的edit_book视图)

    1. 方式一 对象的形式 save同步数据
    2. 方式二 objects管理对象 update方法
      1. 关键字传参
      2. **打散传参
  4. 单表删除操作

  5. 流程

    1552624686590

  6. 删除方式

    1. obj.delete()
    2. queryset.delete() # 有多个时,会全部删除。

四、今日作业

​ 完成图书管理系统的书籍管理,运用bootstrap样式美化

五、ORM多表操作

一、内容回顾

​ 1. 单表操作

	1. 基于双下划线的模糊查询
     		1. __in   判断字段值,是否在里面
     		2. __gt  判断字段值,大于
     		3. __gte  大于等于
     		4. __lt  小于
     		5. __lte  小于等于
     		6. __range  判断字段值,是否在这个范围内。首尾都包含
     		7. __startswith  判断以什么开头。
     		8. __contains  包含
     		9. __icontaions  对大小写不敏感
     		10. pub_date__year   判断年份
  1. 单表的修改
    1. 实例对象通过修改属性。最后要save。
    2. objects提供的方法。update更新。

二、今日概要

​ 一、创建模型

​ 二、对多表的操作

三、今日详细

### 1. 设计表结构

1552874955847

1552876411645

  1. 定义模型

1552876797766

  1. 多表操作

    1. 一对多

​ 添加的两种方式:

  1. 传对象的形式、

    book = models.Book.objects.create(title="打狗棒法", price=160, pub_date="2017-10-11", publish=pub_obj)
    
  2. 传对象id的形式

    book = models.Book.objects.create(title="睡梦罗汉拳", price=160, pub_date="2017-10-11", publish_id=pub_obj.pk)
    
  3. 多对多

  4. 传对象

    book_obj = models.Book.objects.filter(title="降龙十八掌").first()
        ling = models.Author.objects.filter(name="令狐冲").first()
        ying = models.Author.objects.filter(name="任盈盈").first()
        book_obj.authors.add(ling, ying)
    
    1. 传对象id
    book_obj = models.Book.objects.filter(title="打狗棒法").first()
        ling = models.Author.objects.filter(name="令狐冲").first()
        xing = models.Author.objects.filter(name="任我行").first()
        book_obj.authors.add(ling.pk, xing.pk)  # 传对象pk值
    
  5. 查询

​ 正向查询按字段, 反向查询按小写表名。

​ 具体的内容,参见项目query视图。

四、今日作业

​ 自己练习多种形式的跨表查询操作。

1、查询丐帮出版社出版的所有书名和作者名称;
2、查询独孤九剑的作者名称和出版社名称;
3、查询吸星大法的作者的姓名、电话和地址;
4、查询令狐冲写的书籍,在哪些出版社出版过,获取其出版社名称和地址;
5、查询出版社地址为黑木崖,在该出版社出版过书籍的作者姓名和邮箱;

六、ORM聚合分组FQ查询

一. 内容回顾

1. 多表关系及建模
  	1. 一对一   OneToOneField
  	2. 一对多   ForeignKey
  	3. 多对多   ManyToManyField
2. 基于对象的跨表查询(正向按字段,方向按小写表名)
  	1. 一对多的操作
  	2. 一对一的操作
  	3. 多对多操作
  1. 基于双下划线的跨表查询
    1. 一对多的操作
      2. 一对一的操作
      3. 多对多操作

    2. 关联管理器
      1. add
      2. clear
      3. remove
      4. set
      5. create

二. 今日概要

1. ORM练习题
2. 图书管理系统(表结构变化)
3. 聚合查询
4. 分组查询
5. F查询
6. Q查询

三. 今日详细

#### 1. 聚合查询aggregate

​ 计算所有图书的平均价格、最贵价格、最低价格

from django.db.modles import Avg, Sum, Max,Min,Count
models.Book.objects.aggregate(Max('price'), Min('price'), avf_pri=Avg('price'))

​ 默认key:字段名__聚合函数名(小写)

  1. 分组查询annotate

​ 在代码里有备注

  1. F查询

在代码里有备注

  1. Q查询

在代码里有备注

四. 今日作业

​ 自己练习5和6

​ 完善多表的图书管理系统。

七、 Ajax

一、内容回顾

  1. 聚合查询aggregate

​ 聚合函数,查询结果。

  1. 分组查询annotate

​ 分组查询,统计结果

  1. F查询

​ 动态获取字段的值

  1. Q查询

​ or关键字

models.Book.objects.filter(aaa="fdfd", bbb="dfdf")  # and
models.Book.objects.filter(Q(aaa="dfdf")|Q(bbb="dfdfd"))  # or

二、今日概要

Ajax相关

1. 简介
2. 简单案例
3. 计算案例
4. 上传json文件
5. form表单和ajax上传文件

三、 今日详细

一、简介

目前为止,能想服务器发送请求的方式有哪些?

  1. 浏览器URL栏,输入URL,回车;
  2. form表单;
  3. 超链接标签a;
  4. Ajax今日内容。

Ajax请求流程:

1553044791643

1111

1553048097185

form 表单使用注意事项:

  1. input标签 type指定为file;
  2. form标签属性指定为 enctype="multipart/form-data";

视图注意事项:

  1. 获取文件对象用request.FILES.get(filename) ;
  2. request.post,只能获取文件名称。

Ajax上传文件

从input标签获取文件对象图

1553055192684

Ajax请求注意事项:

  1. 先创建 new FormData() 对象(容器);

  2. 前端获取文件对象(参考上图)$(".file_name")[0].files[0];

  3. Ajax配置;

    processData: false,  // 告诉jQuery不要去处理发送的数据
    contentType: false,  // 告诉jQuery不要去设置Content-Type请求头
    

四、今日作业

  1. 基于Ajax实现用户登录

    1553056270680

  2. 基于Ajax实现图书的删除。

八、 cookie与session

一、内容回顾

  1. Ajax请求

    1. 简单示例

      $.ajax({
          url: '/fdf/', # URL
          type: 'POST', # 请求方式
          data:请求数据,
          success:function(data){
          	console.log(data)
      }
      })
      
      1. 计算器示例

        1. jQuery获取值
        2. 发送Ajax请求,将值传到服务器
        3. 服务器获取值,进行逻辑处理,返回结果
        4. 前端,触发回调函数,执行对应的代码。
      2. 上传json文件

        1. contentType:“json”
        2. JSON.stringify()
      3. form表单上传文件

        1. encType=“fdfd/form-data"
        2. input type= file, name=XXX
        3. 服务器获取值,request.FILES.get(XXX)
      4. ajax上传文件

        1. let formdata = new FormData()

        2. formdata.append("key", "val")

        3. 
          
      processData: false,  // 告诉jQuery不要去处理发送的数据
      contentType: false,  // 告诉jQuery不要去设置Content-Type请求头
      ​```
      
      4. data: fromdata,
      
      5. 后台代码一致。
      
    2. 删除流程

    1553131504700

二、今日概要

  1. cookie
  2. session

三、今日详细

  1. cookie简介

1553134568149

  1. 代码设置cookie

​ 第一次请求,登录成功时。1553135804405

​ 第二次请求时。

1553135916855

装饰器的必备条件:

  1. 闭包函数(内部作用域引用外部作用域,而非,全局作用域)

  2. 高阶函数(第一,把函数当参数传入,第二,把函数当返回值返回)

  3. session简介

request.session['username'] = "yuan"
  1. 生成随机字符串
  2. session_key就是存随机字符串,转换成字典,存到django_session表里
  3. 在cookie中设置sessionid=session_key
request.session.get('is_login')
  1. 获取cookie获取sessionid
  2. 拿到这个id去django-session表中过滤对当前对象
  3. 获取值。

四、今日作业

  1. 基于装饰器实现用户登录校验
  2. 完成登录界面的验证码校验。

九、 中间件与session源码

一、内容回顾

二、今日概要

  1. 中间件
  2. session源码

三、今日详细

  1. 中间件

  2. 1115972-20190321212602449-1256109927

  3. session源码

    1. 发送请求,走中间件的process_request方法。

      class SessionMiddleware(MiddlewareMixin):
          def __init__(self, get_response=None):
              self.get_response = get_response
              engine = import_module(settings.SESSION_ENGINE)
              self.SessionStore = engine.SessionStore
      
          def process_request(self, request):
              session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME) # 第一次为None
              request.session = self.SessionStore(session_key)
              
              # reqeust.session是SessionStore的实例化对象
      
    2. 视图函数

      1. request.session["is_login"] = True # 会触发__setiten__方法
        
      2. self._session  # 获取字典。
        _session = property(_get_session)
        
      3. def __setitem__(self, key, value):
            self._session[key] = value
            self.modified = True
            # 给字典赋值
            # self._session["is_login"] = True
        

​ 第一次进来流程图

  1. 1553247287265
  2. 1553247398739
  3. 1553247472501
  4. 1553247544392
  5. 1553247683141
  6. 1553247770984
  7. 1553247906129
  8. 1553247993078

9.1553248103846

  1. 1553248318095

11.1553248399950

四、今日作业

  1. 今日理解中间件的方法,自己练习一遍整理笔记。
  2. 结合笔记,自己整理session源码流程图。
  3. 本周作业:
    1. 继续完成昨天的作业。
      1. 基于session的装饰器登录验证
      2. 登录验证码的使用
    2. 群里有 ORM练习题。

十、form组件和用户认证组件

一、内容回顾

  1. 中间件

  2. process_request视图之前,请求进来第一个执行

  3. process_view视图之前,return后跳至最后一个process_response

  4. process_exception,视图有报错,才会执行。return 后跳至最后一个process_response

  5. process_response 倒序,必须由return response

  6. 解析session源码

  7. process_reqeust

    1. request.session 对象
  8. 视图

    1. request.session["is_login"] = True # 触发__setitem__方法
    2. 找到一个字典。对字典赋值
    3. process_response 方法。
      1. save方法
      2. 存至django_session表
      3. 设置cookie的key为sessionid

二、今日概要

  1. FORM组件
  2. 用户登录认证组件

三、今日详细

  1. form的使用

    1. 自己定义myForm类

      from django import forms
      
      class EmpForm(forms.Form):
          name = forms.CharField(min_length=5, label="姓名", error_messages={"required": "该字段不能为空!",
                                                                           "min_length": "用户名太短。"})
          age = forms.IntegerField(label="年龄")
          salary = forms.DecimalField(max_digits=5, decimal_places=2, label="工资")
      
      

      字段要跟models里的字段保持一致。

    2. 视图返回form对象,完成页面初始化

      form = EmpForm() # GET请求
              return render(request, "login.html", {"form": form})
      
    3. 前端进行渲染

      1. as_p方法
      2. 自己写form对象标签
      3. for循环获取标签
    4. 提交数据

      1. 校验,显示错误信息
      2. 在视图中,走一个is_valid()
        1. 成功的话,form.cleaned_data合法数据。进行数据库操作
        2. 失败的话,form.errors,前端显示错误信息。
  2. form的钩子的使用

    1. 局部钩子

      1. clean_类属性名称
        1. 校验成功,返回对应的值
        2. 校验失败,主动抛出异常
    2. 全局钩子

      1. 导包 from django.core.exceptions import ValidationError
      2. clean全局校验
        1. 成功返回self.cleaned_data
        2. 失败,主动抛出异常。
    3. 流程图

      1553487247222

  3. 用户登录认证组件

    1. 大前提:基于django提供的auth_user表。
    2. authenticate(username=user, password=pwd) # 过滤合法用户。有则返回该对象,无,返回None
    3. auth.login(request, user_obj) # 1.设置session值,request.user = user_obj
    4. auth.logout(request) # 1.清楚session信息 2.把request.user 重新赋值为匿名用户。
  4. User对象

    1. 创建

      1. # User.objects.create(username=user, password=pwd)  # 常规清空下,这样创建用户。密码不安全。明文。
        # user_obj = User.objects.create_user(username=user, password=pwd)  # 创建普通用户
        user_obj = User.objects.create_superuser(username=user, password=pwd, email="alex@163.com")  # 创建超级用户。
        
  5. login_required装饰器

    1. 导入

      from django.contrib.auth.decorators import login_required
      

    2.装饰器的正常使用。

    1. 注意登录的URL设置

      在settings里配置。默认在global_settings里
      LOGIN_URL = '/auth_login/'
      

四、今日作业

  1. 基于form组件实现用户注册登录
  2. 基于用户认证组件,实现登录管理。
posted @ 2019-04-07 13:30  iamironman  阅读(106)  评论(0)    收藏  举报