zoukankan      html  css  js  c++  java
  • Django基础及实战

    day52

    今日内容

    内容规格

    Python的基础

    面向对象

    网络

    并发

    数据库

    前端

    今日内容

    1. web框架 原理
    2. Django的下载安装使用

    百度 socket服务端

    1. socket服务端启动
      2. 绑定ip和端口
      3. 监听等待连接
    2. 接受数据
    3. 返回数据
    4. 断开连接

    浏览器 socket客户端

    4. socket客户端启动
    
    1. 连接(ip和端口)
    2. 发送数据
    3. 接受数据
    4. 断开连接

    https://www.cnblogs.com/maple-shaw/articles/9060408.html

    HTTP协议:

    http是请求和应答的标准

    请求方式:8种 主要是GET POST

    状态码 1xx 2xx 3xx 4xx 5xx

    请求格式:

    ​ ‘请求方式 路径 协议版本

    ​ 请求头: 值

    ​ 请求头: 值

    ​ 请求数据’

    响应格式:

    ​ '协议版本 状态码 状态描述

    ​ 请求头: 值

    ​ 请求头: 值

    ​ 响应数据'

    web框架的实现的功能:

    1. socket收发消息
    2. 根据不同的路径返回不同的内容
    3. 返回HTML页面
    4. 返回动态的页面 (模板的渲染 字符串的替换)

    web框架

    Django 2 3 4

    flask 2 3

    tornado 1 2 3 4

    Django 大而全

    flask tornado 轻量级的框架

    Django

    下载:

    1. 命令行

    pip install -i django==1.11.25 -i https://pypi.tuna.tsinghua.edu.cn/simple

    1. pycharm

      在项目的解释器中找对应的Django版本下载

    创建项目

    1. 命令行

      django-admin 项目名

    2. pycharm

      file ——》 new project ——》 填写项目名称 ——》 选择解释器 ——》 create

    启动项目

    1. 命令行

      python manage.py runserver # 127.0.0.1:8000

      python manage.py runserver 80 # 127.0.0.1:80

      python manage.py runserver 0.0.0.0:80 # 0.0.0.0:80

      1. pycharm

    简单使用

    1. urls.py中写路径和函数的对应关系

      urlpatterns = [
          url(r'^index/', index),
      ]
      
    2. 写函数

      from django.shortcuts import HttpResponse ,render
      def index(request):
          # 逻辑
          # return HttpResponse('欢迎进入day5项目')   # 返回字符串
          return render(request,'index.html')  # 返回一个HTML页面    页面写在templates文件夹中
      

    作业:

    ​ 用bootstrap写登录页面,使用Django返回给浏览器

    day53

    内容回顾

    HTTP

    规定请求和响应的格式。

    请求方法

    8种 GET POST ( PUT DELETE HEAD OPTIONS TRACE CONNECT )

    状态码

    1xx 请求已接受,进一步进行处理

    2xx 请求已经接受,也正常处理

    3xx 重定向

    4xx 请求的错误 403 404

    5xx 服务器的错误

    URL

    https://www.sogou.com/web?query=苍老师&_asf=www.sogou.com

    协议 : https

    域名: www.sogou.com ip

    端口: https (:443) http (:80)

    路径: /web

    查询的参数: ?后面 k1=v1&k2=v2

    请求和响应的格式

    请求(浏览器给服务端发的消息) request

    	‘请求方式 路径 HTTP/1.1
    
    	  k1:v1
    
    	  k2:v2
    

    	  请求数据(请求体)’
    

    响应(服务器返回给浏览器的消息) response

    	'HTTP/1.1 状态码 状态描述
    
    	  k1:v1
    
    	  k2:v2
    

    	  响应数据(响应体)’'
    

    请求和响应的步骤

    1. 在浏览器的地址栏种输入URL地址,回车,发个一个GET请求;
    2. Django接受到请求,根据URL的路径找到对应的函数,执行函数拿到结果
    3. Django将结果封装成http响应的报文返回浏览器
    4. 浏览器接受响应,断开连接,解析数据。

    框架的功能

    1. socket收发消息
    2. 根据不同路径返回不同的结果(返回HTML页面)
    3. 返回动态的页面( 模板的渲染 字符串的替换 )

    Django部分

    1. 下载安装

      命令行:

      pip install django==1.11.25  -i  源
      

      pycharm:

      1. 创建项目

      命令行:

      django-admin startproject 项目名
      

      pycharm

      区别: pycharm创建时帮忙创建一个templates的文件夹,配置了模板的路径

    2. 启动项目

      命令行:

       cd 项目的根目录下
       
       python  manage.py runserver    #  127.0.0.1:8000
       
       python  manage.py runserver 80    #  127.0.0.1:80
       
       python  manage.py runserver 0.0.0.0:80    #  0.0.0.0:80
      

      pycharm:

       点绿三角   相关的配置
      
    3. 使用:

      1. 设计URL 和 函数的对应关系  urls.py
          urlpatterns = [
             url(r'^index/', index),
      	]
      2. 写函数
      	from django.shortcuts import HttpResponse,render  
      	def 函数名(request):
      		# 逻辑 
      		# 查询数据库 插入
      		# 返回信息给浏览器
      		return HttpResponse('字符串')
      		return render(request,‘html文件名’)
      
      

    今日内容

    1.静态文件的配置

    settings:

    STATIC_URL = '/static/'   # 静态文件的别名  以它做开头
    
    STATICFILES_DIRS = [   #  静态文件存放的具体路径
        os.path.join(BASE_DIR,'static',)
    ]
    

    http://www.jq22.com

    2.登录示例

    form表单提交数据

    1. action="" 向当前的地址进行提交 method="post" 请求方式
    2. input需要有name属性 value值
    3. button按钮或者input 类型是submit

    在settings中注释一行代码,注释后可以提交post请求

    MIDDLEWARE
    'django.middleware.csrf.CsrfViewMiddleware' 
    
    request.method  请求方式 GET POST
    request.POST    POST请求的数据  {} 
    redirect(‘要重定向的地址’)   重定向 
    

    3.app

    创建app

    python manage.py startapp app名称

    注册app

    INSTALLED_APPS = [
      	... 
        'app01',
        'app01.apps.App01Config'    # 推荐写法
    ]
    

    app文件目录

    admin.py   admin管理后台  增删改查数据库
    apps.py    app相关
    models.py  数据库表相关
    views.py   写函数(逻辑)
    

    4.ORM

    对应关系

    类 ——》 表

    对象 ——》 数据行(记录)

    属性 ——》 字段

    django要使用mysql数据库流程

    1. 创建一个mysql数据库;

    2. 在settings中配置数据库信息:

      DATABASES = {
          'default': {
              'ENGINE': 'django.db.backends.mysql',   #  引擎  数据库类型
              'NAME': 'day53',				# 数据库名称
              'HOST': '127.0.0.1',			# ip
              'PORT': 3306,					# 端口
              'USER': 'root',					# 用户名
              'PASSWORD': '123'				# 密码
          }
      }
      
    3. 告诉django使用pymysql模块连接数据库

      import pymysql   
      pymysql.install_as_MySQLdb()   # 能执行就可以
      
    4. 在app下写了model

      class User(models.Model):
          username = models.CharField(max_length=32)  # username   varchar(32)
          password = models.CharField(max_length=32)  # username   varchar(32)
      
      
    5. 执行命令 让数据有对应的结构的变化

      python manage.py makemigrations # 检查所有已经注册的app下的models.py的变化 记录成一个文件

      python manage.py migrate

    ORM操作

    from app01.models import User
    User.objects.all()  #  查询所有的数据   QuerySet 对象列表  【  对象 】
    User.objects.get(username='alexs',password='alexdsb')  
    # 对象  get  只能获取数据库唯一存在的数据  有且唯一 (不存在或者多条数据就报错)
    
    User.objects.filter(password='dsb')  # 获取满足条件的所有对象  对象列表
    

    day54

    内容回顾

    1. 下载

      命令行:

       pip install django==1.11.25  -i   源
      

      pycharm:

       file _>   settings  _>  项目  ——》 解释器  ——》  点+号  ——》  输入django  ——》 选择版本 ——》 下载
      

    2.创建项目

    命令行:
    
    	django-admin  startproject  项目名
    
    pycharm:
    
    	file  _>   new project ——》 选择django  ——》 输入项目的路径 ——》 选择解释器  ——》 templates  还有app名称 
    

    3.启动项目

    命令行:
    
    		切换项目的根目录下   manage.py
    
    		python manage.py  runserver     #  127.0.0.1:8000 
    
    		python manage.py  runserver  80   #  127.0.0.1:80
    
    		python manage.py  runserver  0.0.0.0:80   # 0.0.0.0:80
    
    pycharm:
    
    		找绿三角  点击  (前面是django的项目)  
    
    		配置ip和端口
    

    4.settings的配置

    模板文件     TEMPLATES    DIRS    [ os.path.join(BASE_DIR,'templates') ]	
    
    静态文件
    
    			STATIC_URL  ='/static/'    #  静态文件的别名
    
    			STATICFILES_DIRS  = [
    
    				os.path.join(BASE_DIR,'static')	,
    
    				os.path.join(BASE_DIR,'static1')	
    
    		]
    
    数据库配置
    
    APP
    
    中间件
    
    		注释一个  csrf     效果: 可以提交post请求
    
    1. APP

      创建APP

       python manage.py  startapp app名称   
      

      注册APP

       INSTALLED_APPS = [
       
       	'app01',
       
       	'app01.apps.App01Config'   推荐写法
      

      ]

    2. urls.py

      from app01 import views
      
      urlpatterns = [
          url(r'^admin/', admin.site.urls),
          url(r'^login/', views.login),
          url(r'^index/', views.index),
      ]
      
      
    3. views.py

      from django.shortcuts import render,HttpResponse,redirect
      
      def login(request):
      	# 逻辑
      	renturn HttpResponse('xxx')
      

      HttpResponse() 返回的字符串

      render(request,'模板的文件名') 返回HTML页面

      redirect('地址') 重定向

    4. get和post

      get 获取页面 资源

      /sssss/?k1=v1&k2=v2

      request.GET {} request.GET.get('key')

      post 提交数据

      request.POST {} request.POST.get('key')

    5. form的表单

      1. form标签的属性 action='' 提交的地址 method='post' 请求方式 novalidate 不在前端做校验
      2. input标签要有name属性 value的值
      3. 有个type=‘submit’ 的input或者button按钮
    6. django使用mysql的流程:

      1. 创建一个mysql数据库

      2. 在settings中配置数据库的信息

        EGNIGE 引擎 mysql

        NAME 数据库名称

        HOST ip

        PORT 端口 3306

        USER 用户名

        PASSWORD 密码

      3. 告诉使用pymysql替换mysqldb的模块

        写在与settings同级目录下的__init__中:

        import  pymysql
        pymysql.install_as_MySQLdb()
        
      4. 在已经注册的app下的models.py中写类(继承models.Model)

        class User(models.Model):
            username = models.CharField(max_length=32)  #  username  varchar(32)
        
      5. 执行命令

        python manage.py  makemigrations  # 记录了一个models的变更记录
        python manage.py  migrate    # 将models的变更记录同步到数据库中
        
    7. ORM

      对象关系映射

      对应关系

      类 —— 》 表

      对象 ——》 数据行(记录)

      属性 ——》 字段

      ORM能做的事情:

    8. 对数据库中表操作

    9. 对表中的数据操作

      orm具体的操作:

      from app01.models import User
      
      User.objects.all()   # 获取到所有的数据 QuerySet  [User对象]  对象列表
      User.objects.get() # 获取一个对象  只能获取唯一存在的对象   如果不存在或者是多个结果就报错
      User.objects.filter()   # 获取到所有满足条件的对象  QuerySet  [User对象]  对象列表
      

    今日内容

    图书管理系统

    出版社 书籍 作者

    出版社的管理

    展示

    1. 设计URL地址

      from app01 import views
      
      urlpatterns = [
          url(r'^admin/', admin.site.urls),
          url(r'^publisher_list/', views.publisher_list),
      ]
      
    2. 写函数

      def publisher_list(request):
          # 从数据库中获取所有的出版社的信息
          all_publisher = models.Publisher.objects.all()  # 对象列表
      
          # 将数据展示到页面中
          return render(request,'publisher_list.html',{'k1':all_publisher})
      
    3. 模板语法

      {{ 变量  }}
      
      for循环
      {% for i in 变量  %}
      	循环体 {{ i }}
      {% endfor  %}
      

    新增

    方式一:
    models.Publisher.objects.create(name=pub_name,addr=pub_addr)  # 对象
    方式二:
    pub_obj = models.Publisher(name=pub_name,addr=pub_addr)  # 内存中的对象 和数据库没关系
    pub_obj.save()  # 插入到数据库中
    

    删除

    models.Publisher.objects.filter(pid=pid).delete()  # 对象列表 删除
    models.Publisher.objects.get(pid=pid).delete()  # 对象 删除
    

    编辑

     pub_obj.name = pub_name
     pub_obj.addr = pub_addr
     pub_obj.save()  # 将修改提交的数据库
    

    day55

    内容回顾

    1.django中所有的命令

    1. 下载django

      pip install django==1.11.25 -i 源

    2. 创建django项目

      django-admin startproject 项目名

    3. 启动项目

      切换到项目目录下

      python manage.py runserver # 127.0.0.1:8000

      python manage.py runserver 80 # 127.0.0.1:80

      python manage.py runserver 0.0.0.0::80 # 0.0.0.0::80

    4. 创建app

      python manage.py startapp app名称

    5. 数据库迁移的命令

      python manage.py makemigrations # 检测已经注册app下的models变更记录

      python manage.py migrate # 将变更记录同步到数据库中

    2.django的配置

    1. 静态文件

      STATIC_URL = '/static/' # 静态文件的别名

      STATICFILES_DIRS = [ # 静态文件存放的路径

      ​ os.path.join(BASE_DIR ,'static')

      ]

    2. 数据库

      ENGINE mysql

      NAME 数据库名称

      HOST ip

      PORT 端口号

      USER 用户名

      PASSWORD 密码

    3. 中间件

      注释掉 一个 csrf (可以提交POST请求)

    4. app

      INSTALLED_APPS = [

      ​ 'app名称'

      ​ ‘app名称.apps.app名称Config’

      ]

    5. 模板

      TEMPLATES DIRS =[ os.path.join(BASE_DIR ,'templates')]

    3.django使用mysql数据库的流程

    1. 创建一个mysql数据库

    2. 配置数据库连接信息

      ENGINE mysql

      NAME 数据库名称

      HOST ip

      PORT 端口号

      USER 用户名

      PASSWORD 密码

    3. 告诉django使用pymysql替换Mysqldb

      在与settings同级目录下的init文件中写:

      import pymysql
      pymysql.install_as_MySQLdb()
      
    4. 在models中写类(继承models.Model)

      class Publisher(models.MOdel):
          pid = models.AutoField(primry_key=True)
          name = models.CharField(max_length=32,unique=True)
      
    5. 执行数据库迁移的命令

      python manage.py makemigrations # 检测已经注册app下的models变更记录

      python manage.py migrate # 将变更记录同步到数据库中

    4.get和post的区别

    发送get的方式:

    1. 地址栏中输入地址 回车
    2. a 标签
    3. from表单

    ?k1=v1&k2=v2 request.GET.get(key) # url携带的参数

    发送post请求:

    ​ form表单 method ='post'

    form表单

    1. action=''   向当前地址进行提交  method ='post'
    
    1. 所有的input需要有name属性 value
    2. 需要有button或者一个type=‘submit’的input框

    request.POST.get(key)

    5.ORM

    对象关系映射

    对应关系

    ​ 类 ——》 表

    ​ 对象 ——》 数据行(记录)

    ​ 属性 ——》 字段

    ORM操作

    查询
    from app01 import  models
    models.Publisher.objects.all()   #  查询所有的数据    QuerySet 【对象】    对象列表
    models.Publisher.objects.get(name='xxx')  #  查询有且唯一的对象  没有或者是多个就报错
    models.Publisher.objects.filter(name='xxx')   # 查询所有符合条件的对象   QuerySet 【对象】    对象列表
    
    for  i in models.Publisher.objects.all() :
    	print(i)    #  Publisher object   __str__()
        print(i.name)
    
    新增
    models.Publisher.objects.create(name='xxxx',addr='xxxx')
    
    obj = models.Publisher(name='xxxx',addr='xxxx')
    obj.save()
    
    删除
    models.Publisher.objects.filter(pid=pid).delete()
    models.Publisher.objects.get(pip=pid).delete()
    
    编辑
    pub_obj.name = 'xxxx'
    pub_obj.addr = 'xxxx'
    pub_obj.save()
    

    6.模板语法

    render(request,‘模板的文件名’,{ key:value })

    {{  key }}  ——》 value的值
    
    for循环
    {% for i in list  %}
    	{{ forloop.counter  }}
    	{{ i }}
    
    {% endfor  %}
    

    今日内容

    书籍的管理

    外键 描述一对多的关系

    class Book(models.Model):
        title = models.CharField(max_length=32, unique=True)
        pub = models.ForeignKey('Publisher',on_delete=models.CASCADE)
      
    on_delete在2.0版本中是必填的
    on_delete=models.CASCADE(级联删除)
    		  models.SET()
        	  models.SET_DEFAULT   default=值
    		  models.SET_NULL      null=True
              models.DO_NOTHING
    
    

    展示

        all_books = models.Book.objects.all()  # 对象列表
        for book in all_books:
            print(book)
            print(book.title,type(book.title))
            print(book.pub)     # 外键关联的对象
            print(book.pub_id)  # 关联对象的id  直接从数据库查询
    

    新增

    models.Book.objects.create(title=book_name,pub=models.Publisher.objects.get(pk=pub_id))
    models.Book.objects.create(title=book_name,pub_id=pub_id)
    

    模板语法

    {% if  条件  %}
    	满足条件显示的值
    {% endif  %}
    
    
    {% if  条件  %}
    	满足条件显示的值
    {% else %}
    	不满足条件显示的值
    {% endif  %}
    
    
    {% if  条件  %}
    	满足条件显示的值
    {% elif  条件1  %}
    	满足条件显示的值
    {% else %}
    	不满足条件显示的值
    {% endif  %}
    
    

    day56

    内容回顾

    1.django处理请求的流程:

    1. 在地址栏中输入地址,回车发送一个请求;
    2. wsgi服务器接收到http请求,封装request对象;
    3. django根据请求的地址找到对应的函数,执行;
    4. 函数执行的结果,django将结果封装成http响应的格式返回给浏览器。

    2.发请求的途径

    1. 地址栏中输入地址 回车   GET请求
    
    2. a标签  GET请求
    3. form表单  GET/POST
    

    3.get和post的区别

    ​ get 获取页面

    ​ ?k1=v1&k1=v2 request.GET.get() url 上携带的参数

    ​ get请求没有请求体

    ​ post 提交数据

    ​ 提交的数据 在请求体中

    4.函数

    def  func(request):
    	# 逻辑
    	return HttpResponse对象
    
    
    request.GET    url上携带的参数   {} 
    request.POST   POST请求提交的数据    {} 
    request.method  请求方法  GET  POST 
    
    HttpResponse('字符串')     返回字符串
    render(request,'模板文件的名字',{k1:v1})     返回一个HTML页面
    redirect('重定向的地址')    重定向
    

    5.外键

    描述 一对多

    class Publisher(models.Model):
    	name = models.CharField(max_length=32)
    
    
    class Book(models.Model):
    	title = models.CharField(max_length=32)
        pub = models.ForeignKey('Publisher',on_delete=models.CASCADE)    # pub_id
    

    展示

    from app01 import models
    all_books = models.Book.objects.all()
    
    for book in all_books:
        print(book.id)  print(book.pk)
        print(book)   # 对象  __str__
        print(book.title)   
    	print(book.pub)      # 外键关联的对象  print(book.pub.pk)  print(book.pub.name)
        print(book.pub_id)   # 外键关联的对象id
    

    新增

    models.Book.objects.create(title='xxxx',pub=关联的对象)
    models.Book.objects.create(title='xxxx',pub_id=id)
    
    obj =models.Book(title='xxxx',pub=关联的对象)
    obj.save()
    

    删除

    models.Book.objects.filter(id=id).delete()
    models.Book.objects.filter(id=id).first().delete()
    

    编辑

    obj = models.Book.objects.filter(id=id).first()
    obj.title = 'xxxxx'
    # obj.pub = pub_obj
    obj.pub_id = pub_obj.id
    obj.save()
    

    6.模板的语法

    {{ 变量  }}
    
    for循环
    {% for i in list  %}
    	{{ forloop.counter  }}
    	{{ i }}
    {% endfor %}
    
    
    {%  if 条件 %}
    	内容
    {% endif %}
    
    {%  if 条件 %}
    	内容
    {% else %}
    	内容2
    {% endif %}
    
    
    {%  if 条件 %}
    	内容
    {%  elif 条件1 %}
    	内容	
    {% else %}
    	内容2
    {% endif %}
    
    

    今日内容

    作者的管理

    作者 书籍 多对多的关系

    class Author(models.Model):
        name = models.CharField(max_length=32)
        books = models.ManyToManyField('Book')  # 不会生成字段  生成第三张表
    

    展示

    all_authors = models.Author.objects.all()
    for author in all_authors:
            print(author)
            print(author.name)
            print(author.books,type(author.books))  # 多对多的关系管理对象
            print(author.books.all(),type(author.books.all()))  # 关系对象列表
            
    
    all_books = models.Book.objects.all()
    for book in all_books:
    	book  # 书籍对象
    	book.title
    	book.author_set         # 多对多的关系管理对象
    	book.author_set.all()   # 书籍关联的所有的作者对象  对象列表  
    
    

    新增

    author_obj = models.Author.objects.create(name=author_name)  # 插入作者信息
    author_obj.books.set(book_id) # 设置作者和书籍的多对多的关系
    

    多对多关系表的创建方式:

    1. django自己创建

      class Book(models.Model):
          title = models.CharField(max_length=32, unique=True)
          pub = models.ForeignKey('Publisher', on_delete=models.CASCADE)
       
      
      class Author(models.Model):
          name = models.CharField(max_length=32)
          books = models.ManyToManyField('Book')  # 不会生成字段  生成第三张表
      
    2. 自己手动创建

      class Book(models.Model):
          title = models.CharField(max_length=32, unique=True)
      
      
      class Author(models.Model):
          name = models.CharField(max_length=32)
      
      
      class AuthorBook(models.Model):
          book = models.ForeignKey('Book',on_delete=models.CASCADE)
          author = models.ForeignKey('Author',on_delete=models.CASCADE)
          date = models.CharField(max_length=32)
      
      
    3. 半自动创建(自己手动创建表 + ManyToManyField 可以利用查询方法 不能用set)

      class Book(models.Model):
          title = models.CharField(max_length=32, unique=True)
      
      class Author(models.Model):
          name = models.CharField(max_length=32)
          books = models.ManyToManyField('Book',through='AuthorBook')  # 只用django提供的查询方法  不用创建表 用用户创建的表AuthorBook
      
      class AuthorBook(models.Model):
          book = models.ForeignKey('Book',on_delete=models.CASCADE)
          author = models.ForeignKey('Author',on_delete=models.CASCADE)
          date = models.CharField(max_length=32)
      
      
      class Book(models.Model):
          title = models.CharField(max_length=32, unique=True)
      
      
      class Author(models.Model):
          name = models.CharField(max_length=32)
          books = models.ManyToManyField('Book',through='AuthorBook',through_fields=['author','book'])  # 只用django提供的查询方法  不用创建表 用用户创建的表AuthorBook
      
      
      class AuthorBook(models.Model):
          book = models.ForeignKey('Book',on_delete=models.CASCADE,null=True)
          author = models.ForeignKey('Author',on_delete=models.CASCADE,related_name='x1',null=True)
          tuiianren = models.ForeignKey('Author',on_delete=models.CASCADE,related_name='x2',null=True)
          date = models.CharField(max_length=32)
      
      

    周末

    学员管理系统

    学生表 班级表 教师表

    day57

    内容回顾

    1.django的命令

    1. 下载

      pip install django==1.11.25 -i 源

      1. 创建项目

      django-admin startproject 项目名

    2. 启动项目

      cd 项目的根目录

      python manage.py runserver # 127.0.0.1:8000

      python manage.py runserver 80 # 127.0.0.1:80

      python manage.py runserver 0.0.0.0:80 # 0.0.0.0:80

    3. 创建APP

      python manage.py startapp app名称

    4. 数据库迁移的命令

      python manage.py makemigrations # 检查已经注册的APP下的models.py的变更记录

      python manage.py migrate # 将变更记同步到数据库中

    2.django的配置

    ​ TEMPLATES 模板 DIRS [ os.path.join(BASE_DIR,'templates') ]

    ​ 静态文件

    ​ STATIC_URL = '/static/' # 静态文件的别名

    ​ STATICFILES_DIRS = [

    ​ os.path.join(BASE_DIR,'static')

    ​ ]

    ​ 注册的app

    ​ INSTALLED_APPS = [

    ​ 'app01'

    ​ 'app01.apps.App01Config'

    ​ ]

    ​ 中间件

    ​ 注释掉csrf中间件 可以提交POST请求

    ​ 数据库的配置

    ​ ENGINE : mysql

    ​ NAME: 数据库的名称

    ​ HOST: ip

    ​ PORT : 3306

    ​ USER : 用户名

    ​ PASSWORD : 密码

    3.django使用mysql数据库的流程

    1. 创建一个mysql数据库

    2. 数据库settings中的配置

      ​ ENGINE : mysql

      ​ NAME: 数据库的名称

      ​ HOST: ip

      ​ PORT : 3306

      ​ USER : 用户名

      ​ PASSWORD : 密码

    3. 告诉django使用pymysql连接数据库

      写在与settingst同级目录下的__init__.py中:

      import pymysql

      pymysql.install_as_MySQLdb()

    4. 在models写类(继承models.Model):

      class Publisher(models.Model):
          pid = models.AutoField(primary_key=True)
          name = models.CharField(max_length=32)  # varchar(32)
          
          
      class Book(models.Model):
          title = models.CharField(max_length=32)  # varchar(32)
          pub = models.ForeignKey('Publisher',on_delete=models.CASCADE)
          
          
      class Author(models.Model):
          name = models.CharField(max_length=32)  # varchar(32)
          books = models.ManyToManyField(Book)  # 生成第三张表  不会在Author表中生成字段
      
    5. 执行数据库迁移的命令

      python manage.py makemigrations # 检查已经注册的APP下的models.py的变更记录

      python manage.py migrate # 将变更记同步到数据库中

    4.request 请求相关的内容

    ​ request.GET url上携带的参数 {} get()

    ​ request.POST POST请求提交的数据 {} get() getlist()

    ​ request.method 请求方法 GET POST

    5.响应

    ​ HttpResponse(‘字符串’) 返回的字符串‘

    ​ render(request,'模板的文件名',{}) 返回的是 完整的页面

    ​ redirect(重定向的地址 ) 重定向

    6.ORM

    ​ 对象关系映射

    ​ 对应关系:

    ​ 类 ——》 表

    ​ 对象 ——》 数据行(记录)

    ​ 属性 ——》 字段

    具体的操作:

    查询

    from app01 import  models
    models.Publisher.objects.all()   #  查询所有的数据  QuerySet  对象列表
    models.Publisher.objects.get(name='xxx')   #  查询满足条件的一条数据(唯一存在) 对象 不存在或者多个就报错
    ret = models.Publisher.objects.filter(name='xxx')   #  查询满足条件所有的数据   对象列表
    ret[0]
    ret.first()   #  获取第一个对象  取不到就是None
    
    
    for i in pubs:
    	i.name
        i.pid   i.pk
        
    book_obj.title
    book_obj.pub    #  外键关联的对象
    book_obj.pub_id    #  外键关联对象的id
    
    
    author_obj.name
    author_obj.books   # 关系管理对象
    author_obj.books.all()   # 所关联的所有的对象   [book,book]
    

    新增

    ret =  models.Publisher.objects.create(name='xxxx')  #  新增数据  返回一个对象
    obj = models.Publisher(name='xxxx')
    obj.save()
    
    models.Book.objects.create(title='xxxx',pub=出版社对象) 
    models.Book.objects.create(title='xxxx',pub_id=出版社对象id) 
    
    obj = models.Author.objects.create(name='xxx')
    obj.books.set([book的id])
    

    删除

     models.Publisher.objects.filter(pk=pk).delete()
     book_obj.delete()
    

    编辑

    book_obj.title = 'xxxx'
    book_obj.pub_id =id
    book_obj.save()
    
    author_obj.name='xxx'
    author_obj.save()
    author_obj.books.set([book的id,book的id,book的id])
    

    7.模板

    render(request,'模板的文件名',{k1:v1})
    
    变量
    {{  k1 }}
    
    for循环
    {% for i in list %}
    	{{ forloop.counter }}
    	{{ i }}
    {% endfor %}
    
    if判读
    
    {% if 条件 %}
    	满足条件后的结果
    {% endif  %}
    
    
    {% if 条件 %}
    	满足条件后的结果
    {% else %}	
    	不满足条件后的结果
    {% endif  %}
    
    
    {% if 条件 %}
    	满足条件后的结果
    {% elif 条件1 %}
    	满足条件后的结果	
    {% else %}	
    	不满足条件后的结果
    {% endif  %}
    
    

    内容回顾

    1.MVC和MTV

    MVC

    ​ M: model 模型 数据库交互

    ​ V:view 视图 展示给用户看的 HTML

    ​ C :controller 控制器 业务逻辑 传递指令

    MTV:

    ​ M: model 模型 ORM

    ​ T: template 模板

    ​ V: view 视图 业务逻辑

    2.变量

    1.点的使用

    {{ 变量 }}

    .索引 . key .属性 .方法

    优先级:

    key > 属性或者方法 > 数字索引

    过滤器

    {{ value|filter_name }}

    {{ value|filter_name:参数 }}

    内置的过滤器

    https://docs.djangoproject.com/en/1.11/ref/templates/builtins/#built-in-filter-reference

    default

    {{  变量|default:'默认值'  }}   变量不存在或者为空 显示默认值
    

    filesizeformat

    显示文件大小

    add

    {{ 2|add:'2'  }}   数字加法
    {{ 'a'|add:'b'  }}   字符串的拼接
    {{ [1,2]|add:[3,4]  }}   列表的拼接
    

    length

    返回变量的长度

    slice

    切片

    {{ string|slice:'-1::-1' }}
    

    date 日期格式化

    {{ now|date:'Y-m-d H:i:s' }}
    

    safe

    {{ a|safe }}  告诉django不需要进行转义 
    
    
    自定义过滤器
    1. 在app下创建一个名叫templatetags的python包 (templatetags名字不能改)

    2. 在包内创建py文件 (文件名可自定义 my_tags.py)

    3. 在python文件中写代码:

      from django import template
      register = template.Library()  # register名字不能错
      
    4. 写上一个函数 + 加装饰器

      @register.filter
      def str_upper(value,arg):  # 最多两个参数
          ret = value+arg
          return ret.upper()
      

    使用:

    ​ 在模板中

    {% load my_tags  %}
    {{ 'alex'|str_upper:'dsb'  }}
    

    day58

    内容回顾

    1.MVC和MTV

    MVC:

    ​ M: model 模型 和数据库交互

    ​ V: view 视图 展示数据 HTML

    ​ C: controller 控制器 业务流程 传递指令

    MTV:

    ​ M: model 模型 ORM

    T:template 模板  HTML 
    

    ​ V : view 视图 业务逻辑

    2.模板

    变量

    render(request,‘模板的文件名’,{ k1:v1 })

    {{ 变量 }}

    {{ 变量.0 }}

    {{ 变量.key }}

    {{ 变量.keys }} {{ 变量.values }} {{ 变量.items }}

    {{ 变量.属性 }} {{ 变量.方法 }}

    优先级:

    字典的key > 方法或者属性 > 数字索引

    过滤器

    修改变量的显示结果

    语法:

    {{ 变量|filter_name }} {{ 变量|filter_name:参数 }}

    内置的过滤器

    default 变量不存在或者为空的时候使用默认值 {{ 变量|default :‘默认值’ }}

    add + 数字的加法 字符串和列表的拼接

    length 返回变量的长度

    filesizeformat 文件大小格式化 byte PB

    upper lower join

    slice 切片 {{ list|slice:'1:2:2' } }

    date 日期时间格式化 {{ 日期时间类型|date:'Y-m-d H:i:s' }} datetime: Y-m-d H:M:S

    ​ settings:

    ​ USE_L10N = False

    ​ DATETIME_FORMAT = 'Y-m-d H:i:s'

    ​ DATE_FORMAT = 'Y-m-d'

    safe 前面的内容不用转义 在模板中使用

    from django.utils.safestring import mark_safe  # py文件中用
    

    自定义过滤器

    1. 在app下创建一个名为templatetags的python包;

    2. 在包内创建py文件 (任意指定,my_tags.py)

      1. 在py文件中写代码
      from  django import template
      register = template.Library()   #  register名字不能错
      
      1. 写函数 + 加装饰器
      @register.filter
      def str_upper(value,arg):
      	return  ''  
      

    使用:

    ​ 模板中使用:

    {% load my_tags  %}
    {{ 变量|str_upper:‘参数’ }}
    

    今日内容

    {% %} tag

    for

    {%  for i in list %}
    	{{ forloop.counter }}
    	{{ i }}
    {% endfor  %}
    
    {{ forloop.counter }}      循环的索引 从1开始
    {{ forloop.counter0 }}     循环的索引 从0开始
    {{ forloop.revcounter }}   循环的索引(倒叙) 到1结束
    {{ forloop.revcounter0 }}   循环的索引(倒叙) 到0结束
    {{ forloop.first }}        判断是否是第一次循环  是TRUE
    {{ forloop.last }}         判断是否是最后一次循环  是TRUE
    {{ forloop.parentloop }}   当前循环的外层循环的相关参数
    
     {% for tr in table %}
                <tr>
                    {% for td in tr %}
                        <td > {{ td }} </td>
                    {% endfor %}
                </tr>
            {% empty %}
                <tr> <td colspan="4" >没有数据</td> </tr>
    {% endfor %}
    

    if

    {% if alex.age == 84 %}
        当前已经到了第二个坎了
    {% elif alex.age == 73 %}
        当前已经到了第一个坎了
    {% else %}
        不在坎上,就在去坎上的路上
    {% endif %}
    
    

    注意:

    1. 不支持算数运算  + - * / % 
    
    2. 不支持连续判断    10 > 5 > 1  false
    

    with

    {% with p_list.0.name as alex_name %}
        {{ alex_name }}
        {{ alex_name }}
        {{ alex_name }}
        {{ alex_name }}
    {% endwith %}
    
    {% with alex_name=p_list.0.name   %}
        {{ alex_name }}
        {{ alex_name }}
        {{ alex_name }}
        {{ alex_name }}
    {% endwith %}
    

    csrf 跨站请求伪造

    {% csrf_token %}  form表单中有一个隐藏的input标签  name='csrfmiddlewaretoken' value 随机字符串
    可以提交post请求
    

    母版和继承

    母版:

    1. 就是一个HTML页面,提取到多个页面的公共部分;
    
    2. 定义block块,留下位置,让子页面进行填充
    

    继承:

    1. 写{% extends  ‘母版的名字’ %}
    
    2. 重写block块
    

    注意点:

    ​ 1. {% extends 'base.html' %} 母版的名字有引号的 不带引号会当做变量

    1. {% extends 'base.html' %} 上不要写内容,想显示的内容要写在block块中
    2. 多定义点block块,有css js

    母版

    继承母版

    组件

    一小段HTML代码 ——》 nav.html

    {% include 'nav.html' %}
    

    静态文件

    {% load static %}
    {% static '相对路径' %}
    
    {% get_static_prefix %}    获取静态文件的别名
    

    simple_tag 和 inclusion_tag

    自定义simple_tag:

    1. 在app下创建一个名为templatetags的python包;

    2. 在包内创建py文件 (任意指定,my_tags.py)

    3. 在py文件中写代码

      from  django import template
      register = template.Library()   #  register名字不能错
      
    4. 写函数 + 加装饰器

      @register.simple_tag
      def str_join(*args, **kwargs):
          return '*'.join(args) + '_'.join(kwargs.values())  
          
          
      @register.inclusion_tag('page.html')
      def page(num):
          return {'num':range(1,num+1)}
          
      # 在templates写page.html
      

    使用:

    ​ 模板中使用:

    {% load my_tags  %}
    {{ 变量|str_upper:‘参数’ }}
    
    {% str_join '1' '2' '3' k1='4' k2='5'  %}
    
    {% page 10 %}
    

    day59

    内容回顾

    模板

    变量

    {{ 变量 }}

    .key .属性 .方法 .索引

    过滤器

    {{ 变量|过滤器 }} {{ 变量|过滤器:参数 }}

    default add filesizeformart date safe join truncatechars

    for 循环

    {% for i in list %}

    ​ {{ i }} {{ forloop }}

    {% endfor %}

    forloop .counter 当前循环的序号 从1开始

    forloop .counter0 当前循环的序号 从0开始

    forloop .revcounter 当前循环的序号 到1结束

    forloop .revcounter0 当前循环的序号 到0结束

    forloop .first 当前循环是否是第一次循环 布尔值

    forloop . last 当前循环是否是最后一次循环 布尔值

    forloop .parentloop 当前循环的外层循环的参数

    for ... empty

    {% for i in list %}

    ​ {{ i }} {{ forloop }}

    {% empty %}

    ​ list 为空的时候

    {% endfor %}

    if判断

    {% if 条件 %}

    ​ 显示的内容

    {% endif %}

    {% if 条件 %}

    ​ 显示的内容

    {% elif 条件1 %}

    ​ 显示的内容

    {% endif %}

    {% if 条件 %}

    ​ 显示的内容

    {% elif 条件1 %}

    ​ 显示的内容

    {% else%}

    ​ 显示的内容

    {% endif %}

    if 要注意的内容:

    1. 不支持算数运算 (过滤器) 
    
    2. 不支持连续判断  (10>5>1)
    

    with

    {% with alex.name as alex_name %}

    ​ {{ alex_name }}

    {% endwith %}

    {% with alex_name=alex.name %}

    ​ {{ alex_name }}

    {% endwith %}

    csrf_token

    {% csrf_token %}写在form标签内,form标签有一个隐藏的input标签,name=‘csrfmiddlewaretoken’

    母版和继承

    母版:

    ​ 本身就是一个HTML页面,提取到多个页面的公共部分,页面中定义多block块。

    子页面继承:

    1. {% extends  ‘母版文件名’ %}
    
    2. 重写block块
    

    注意点:

    1. {% extends  ‘母版文件名’ %}   文件名带引号   不带引号当做变量
    
    2. {% extends  ‘母版文件名’ %}  上面不要写内容   想要显示的内容写在block块中
    3. 母版中多定义写block块  css  js
    

    组件

    ​ 一小段HTML代码段 ——》 HTML文件中

    ​ {% include 'nav.html' %}

    静态文件

    ​ {% load static %}

    ​ {% static '相对路径' %}

    ​ {% get_static_prefix %} STATIC_URL

    模板自定义方法

    filter simple_tag inclusion_tag

    定义:

    1. 在已注册的app下创建templatetags的python包;

    2. 在包中创建py文件 (文件名任意指定 my_tags.py)

    3. 在py文件中写固定的代码:

      from  django  import template
      register = template.Library()   #  register的名字也不能错
      
      1. 写函数 + 加装饰器
      # filter
      @register.filter
      def str_upper(value,arg)  
      	return 'xxxxx'
      
      #simple_tag
      @register.simple_tag
      def str_join(*args,**kwargs):
      	return 'xxxxx'
      
      #inclusion_tag
      @register.inclusion_tag('li.html')
      def show_li(num,*args,**kwargs):
          return {'num':range(1,num+1)}
      
      # li.html
      <ul>
      	{% for i in num %}
          	<li>{{ i }}</li>
          {% endfor %}
      </ul>
      
      

    使用:

    {% load my_tags  %}
    
    {{ 'xxx'|str_upper:'参数'  }}   
    
    {% str_join 1 2 3 k1=4 k2=5 %}
    
    {% show_li 3 %}
    ' 
    <ul>
    	<li>1</li>
    	<li>2</li>
    	<li>3</li>
    </ul>
    '
    

    今日内容

    视图

    MVC MTV

    FBV 和 CBV

    FBV function based view

    CBV class based view

    定义CBV

    from django.views import View
    class PublisherAdd(View):
        
        def get(self,request):
            # 处理get请求的逻辑
            return response
        
        def post(self,request):
            # 处理post请求的逻辑
            return response
    
    

    写对应关系

     url(r'^publisher_add/', views.PublisherAdd.as_view()),
    

    as_view的流程

    1. 程序加载时,执行View中as_view的方法 ,返回一个view函数。

    2. 请求到来的时候执行view函数:

      1. 实例化类 ——》 self

      2. self.request = request

      3. 执行self.dispatch(request, *args, **kwargs)

        1. 判断请求方式是否被允许:

          1. 允许

            通过反射获取当前对象中的请求方式所对应的方法

            handler = getattr(self, request.method.lower(), self.http_method_not_allowed)

          2. 不允许

            handler = self.http_method_not_allowed

            1. 执行handler 获取到结果,最终返回给django

    装饰器补充

    from functools import wraps
    
    
    def wrapper(func):
        @wraps(func)
        def inner(*args, **kwargs):
            # 之前
            ret = func(*args, **kwargs)
            # 之后
            return ret
    
        return inner
    

    django中给视图加装饰器

    FBV 直接给函数添加装饰器

    CBV

    from django.utils.decorators import method_decorator

    1. 加在方法上

      @method_decorator(wrapper)
      def get(self,request):
      
    2. 加在dispatch方法上

      @method_decorator(wrapper)
          def dispatch(self, request, *args, **kwargs):
              ret = super().dispatch(request, *args, **kwargs)
              return ret
      
      
      @method_decorator(wrapper, name='dispatch')
      class PublisherAdd(View):
      
    3. 加在类上

      @method_decorator(wrapper, name='post')
      @method_decorator(wrapper, name='get')
      class PublisherAdd(View):
      

    request

    request.method    # 请求方式
    request.GET		#  URL上携带的参数
    request.POST	# POST请求提交的数据   enctype="application/x-www-form-urlencoded"
    request.FILES	# 上传的文件   enctype="multipart/form-data"
    request.path_info   # 路径信息  不包含IP和端口  也不包含查询参数
    request.body   # 请求体 原始数据
    request.COOKIES  # cookies
    request.session  # session
    request.META   # 请求头的信息
    
    request.get_full_path() # 路径信息  不包含IP和端口 包含查询参数
    request.is_ajax()   # 是否是ajax请求 布尔值
    

    response

    HttpResponse('字符串')    # 返回字符串
    render(request,'模板的文件名',{})   # 返回一个页面
    redirect(地址) # 重定向   响应头 Location: 地址
    

    day60

    内容回顾

    视图

    FBV CBV

    定义CBV

    from django.views import View
    class PUblisherAdd(View):
        # http_method_names = ['get',]
        
        def get(self,request,*args,**kwargs):
            # 处理GET请求的具体的逻辑
            self.request
            return response
        
        def post(self,request,*args,**kwargs):
            # 处理GET请求的具体的逻辑
            return response
    
    

    ulrs.py中写对应关系

    url(r'add_publisher/',views.PublisherAdd.as_view())
    

    as_view的流程

    1. 程序启动的时候,类.as_view()方法要执行 ——》 view函数

    2. 请求到来的时候要执行view函数

      1. 实例化类 成对象 ——》 self

      2. self.request = request

      3. 执行dispatch的方法

        1. 判断请求方式是否被允许; http_method_names = []

          1. 允许

            通过反射获取对应请求方式所对应的方法 ——》 handler

          2. 不允许

            http_methid_not_allowed ——》 handler

        2. 执行handler 返回它的执行结果

    加装饰器的方法

    form functools import wraps
    
    def timer(func):
    	@wraps(func)
    	def inner(*args,**kwargs):
    		# 之前的操作
    		ret = func(*args,**kwargs)
    		# 之后的操作
    		return ret
    	return inner
    

    FBV 直接加

    CBV

    from django.utils.decorators import method_decorator

    1. 加在方法上
    @method_decorator(timer)
    def get(....)
    
    2. 加在类上
    @method_decorator(timer,name='get')
    class PUblisherAdd(View):
    
    3. 加在dispatch方法上
    @method_decorator(wrapper)
    def dispatch(self, request, *args, **kwargs):
        ret = super().dispatch(request, *args, **kwargs)
        return ret
    
    @method_decorator(timer,name='dispatch')
    class PUblisherAdd(View):
    

    request对象

    request.GET   #  url上携带的参数  {} 
    request.POST  # POST请求提交的数据   编码类型urlencode
    request.method  # 请求方式 POST GET 
    request.FILES  # 上传的文件
    	1. enctype="multipart/form-data"
        2. input type = 'file'  name='f1'
    request.path_info   # 路径信息  不包含ip和端口  也不包含查询的参数
    request.body   # 请求体  浏览器提交的原始数据
    request.META   # 请求头的信息  小写 ——》  大写  - ——》 _  HTTP_
    request.COOKIES  # COOKIE 
    request.session  # session 
    
    request.get_full_path()  # 完整的路径信息  不包含ip和端口  包含查询的参数 
    request.is_ajax()     # 是否是ajax请求
    

    response对象

    HttpRsponse('字符串')     # 返回字符串   Content-Type: text/html; charset=utf-8
    render(request,'模板的文件名',{})   # 返回一个HTML页面
    redirect(地址)  # 重定向到地址    本质:响应头 Location:地址
    JsonResponse({})   # 返回json数据   返回非字典类型safe=False  Content-Type: application/json
    
    

    路由

    URLconf

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^blog/$', views.blogs),  # /blog/
        url(r'^blog/[0-9]{4}/d{2}/$', views.blog), # /blog/2019/10/
        
    ]
    
    url(正则表达式的字符串, 视图函数,)
    

    正则表达式

    ​ r'' ^ 开通 $ 结尾 [0-9a-zA-Z]{4} d w . ? 0个或1个 *0个或无数个 + 至少一个

    分组

    urlpatterns = [
    
        url(r'^blog/([0-9]{4})/(d{2})/$', views.blog),
    
    ]
    

    从URL上捕获参数,将参数按照位置传参传递给视图函数。

    命名分组

    urlpatterns = [
    
        url(r'^blog/(?P<year>[0-9]{4})/(?<month>d{2})/$', views.blog),
    
    ]
    

    从URL上捕获参数,将参数按照关键字传参传递给视图函数。

    include

    from django.conf.urls import url, include
    from django.contrib import admin
    
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    
        url(r'^app01/', include('app01.urls')),
        url(r'^app02/', include('app02.urls')),
    
        url(r'^file_upload/', views.file_upload),
        url(r'^get_data/', views.get_data),
    
    ]
    
    

    app01 urls,py

    from django.conf.urls import url
    
    
    from app01 import views
    
    urlpatterns = [
    
        url(r'^publisher_list/', views.publisher_list),
        # url(r'^publisher_add/', views.publisher_add),
        url(r'^publisher_add/', views.PublisherAdd.as_view()),
        # url(r'^publisher_add/', view),
        url(r'^publisher_del/(d+)/', views.publisher_del),  
        url(r'^publisher_edit/', views.publisher_edit),
        
    ]
    

    URL的命名和反向解析

    静态路由

    URL的命名

    url(r'^publisher_list/', views.publisher_list, name='publisher_list'),
    

    URL反向解析

    模板

    {% url 'publisher_list' %}    ——》  解析生成完整的URL路径  '/app01/publisher_list/'
    

    py文件

    from django.shortcuts import render, redirect, HttpResponse, reverse
    from django.urls import reverse
    
    reverse('publisher_list')   ——》  '/app01/publisher_list/'
    

    分组

    URL的命名

     url(r'^publisher_del/(d+)/', views.publisher_del,name='publisher_del'),
    

    URL反向解析

    模板

    {% url 'publisher_del' 1  %}    ——》  解析生成完整的URL路径  '/app01/publisher_del/1/'
    

    py文件

    from django.shortcuts import render, redirect, HttpResponse, reverse
    from django.urls import reverse
    
    reverse('pub_del',args=(1,))   ——》  '/app01/publisher_del/1/'
    

    命名分组

    URL的命名

     url(r'^publisher_del/(d+)/', views.publisher_del,name='publisher_del'),
    

    URL反向解析

    模板

    {% url 'publisher_del' 1  %}    ——》  解析生成完整的URL路径  '/app01/publisher_del/1/'
    {% url 'publisher_del' pk=1  %}    ——》  解析生成完整的URL路径  '/app01/publisher_del/1/'
    

    py文件

    from django.shortcuts import render, redirect, HttpResponse, reverse
    from django.urls import reverse
    
    reverse('pub_del',args=(1,))   ——》  '/app01/publisher_del/1/'
    reverse('pub_del',kwargs={'pk':1})   ——》  '/app01/publisher_del/1/'
    

    namespace

    urlpatterns = [
    
        url(r'^app01/', include('app01.urls', namespace='app01')),  # home   name=home
        url(r'^app02/', include('app02.urls', namespace='app02')),  # home   name=home
    
    ]
    
    

    反向解析生成URL

    {% url 'namespace:name' % }

    reverse( 'namespace:name' )

    day61

    内容回顾

    路由系统

    urlconf

    from django.conf.urls import url
    
    from app01 import views
    urlpatterns = [
    
        url(r'^publisher_list/', views.publisher_list, name='publisher_list'),
        # url(r'^publisher_add/', views.publisher_add),
    ]
    

    正则表达式

    从上到下进行匹配,匹配到一个就不再往下匹配

    r $ ^ d w [a-z] [azs]{4} . ? + *

    分组和命名分组

    url(r'^(publisher)_list/', views.publisher_list, name='publisher_list'),
    

    从URL地址上捕获的参数会按照 位置参数 传递给视图函数

    url(r'^(?P<xxx>publisher)_list/', views.publisher_list, name='publisher_list'),
    

    从URL地址上捕获的参数会按照 关键字参数 传递给视图函数

    include 路由分发

    from django.conf.urls import url, include
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    
        url(r'^app01', include('app01.urls')),
        url(r'^app02/', include('app02.urls')),
    ]
    

    URL的命名和反向解析

    静态路由

    url(r'^publisher_list/', views.publisher_list, name='publisher'),
    

    反向解析

    模板

    {% url 'publisher' %}   ——》 /app01/publisher_list/
    

    py文件

    from django.urls import reverse
    reverse('publisher')    ——》  /app01/publisher_list/
    

    分组

    url(r'^(publisher)_list/', views.publisher_list, name='publisher'),
    

    反向解析

    模板

    {% url 'publisher' 'publisher' %}   ——》 /app01/publisher_list/
    

    py文件

    from django.urls import reverse
    reverse('publisher',args=('publisher',))    ——》  /app01/publisher_list/
    

    命名分组

    url(r'^(?P<xx>publisher)_list/', views.publisher_list, name='publisher'),
    

    反向解析

    模板

    {% url 'publisher' 'publisher' %}   ——》 /app01/publisher_list/
    {% url 'publisher' xx='publisher' %}   ——》 /app01/publisher_list/
    

    py文件

    from django.urls import reverse
    reverse('publisher',args=('publisher',))    ——》  /app01/publisher_list/
    reverse('publisher',kwargs={'xx':'publisher'})    ——》  /app01/publisher_list/
    

    namespace

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
    
        url(r'^app01', include('app01.urls',namespce='app01')),
        url(r'^app02/', include('app02.urls')),
    ]
    

    {% url namespace:name %}

    reverse('namespace:name ')

    今日内容

    常用字段

    AutoField       自增  primary_key = True主键
    
    IntegerField    整形 -21亿  - 21亿
    
    BooleanField     布尔值类型
    
    NullBooleanField  可以为空的布尔值
    
    CharField      字符串
    
    TextField      文本类型
    
    DateTimeField   日期+加时间
    
    DateField     日期格式
        
    TimeField     时间格式
    
    FloatField    浮点型
    
    DecimalField(max_difits=6,decimal_piaces=3)   十进制小数
    

    字段参数

    null = True    数据库中该字段可以为空
    
    black = True    用户输入可以为空
    
    default         默认值
    
    db_index=True 索引
    
    unique    唯一约束
    
    verbose_name   显示的名称
    
    choices   可选择的参数
    

    使用admin的步骤:

    1. 创建一个超级用户

      python manage.py createsuperuser
      输入用户名及密码
      

    2.在app下的admin.py 中注册model

    from django.contrib import admin 
    from app01 import models
    #Register your models here.
    admin.site.register(models.Person)
    

    3.地址栏输入/admin/

    必知必会13条

    import os
    
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")
    import django
    
    django.setup()
    
    from app01 import models
    
    # all()   获取所有的数据  QuerySet  对象列表
    ret = models.Person.objects.all()
    
    # get()   获取一个对象  对象  不存在或者多个就报错
    # ret = models.Person.objects.get(name='alexdsb')
    
    # filter()   获取满足条件的所有对象  QuerySet  对象列表
    ret = models.Person.objects.filter(name='alexdsb')
    
    # exclude()  获取不满足条件的所有对象   QuerySet  对象列表
    ret = models.Person.objects.exclude(name='alexdsb')
    
    # values  QuerySet   [ {} ]
    # values()  不写参数  获取所有字段的字段名和值
    # values('name','age')  指定字段 获取指定字段的字段名和值
    ret = models.Person.objects.values('name', 'age')
    # for i in ret:
    #     print(i,type(i))
    
    # values_list  QuerySet   [ () ]
    # values_list()  不写参数  获取所有字段的值
    # values_list('name','age')  指定字段 获取指定字段的值
    
    ret = models.Person.objects.values_list('age', 'name')
    
    # for i in ret:
    #     print(i, type(i))
    
    # order_by   排序  默认升序   降序 字段名前加-   支持多个字段
    ret = models.Person.objects.all().order_by('-age', 'pk')
    
    
    # reverse  对已经排序的结果进行反转
    ret = models.Person.objects.all().order_by('pk')
    ret = models.Person.objects.all().order_by('pk').reverse()
    
    # distinct mysql不支持按字段去重
    ret = models.Person.objects.all().distinct()
    
    ret = models.Person.objects.values('name','age').distinct()
    
    # count()  计数
    ret = models.Person.objects.all().count()
    ret = models.Person.objects.filter(name='alexdsb').count()
    
    # first  取第一个元素  取不到是None
    ret = models.Person.objects.filter(name='xxxx').first()
    
    # last  取最后一个元素
    ret = models.Person.objects.values().first()
    
    # exists  是否存在  存在是True
    ret = models.Person.objects.filter(name='xx').exists()
    print(ret)
    
    
    """
    返回对象列表  QuerySet
    all()  
    filter() 
    exclude()
    values()    [ {},{} ]
    values_list()    [ (),() ]
    order_by()
    reverse() 
    distinct()
    
    
    返回对象
    get
    first
    last
    
    返回数字
    count
    
    返回布尔值
    exists() 
    """
    

    单表的双下划线

    import os
    
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")
    import django
    
    django.setup()
    
    from app01 import models
    
    ret = models.Person.objects.filter(pk__gt=3)  # gt  greater than 大于
    ret = models.Person.objects.filter(pk__lt=3)  # lt  less than   小于
    
    ret = models.Person.objects.filter(pk__gte=3)  # gt  greater than equal  大于等于
    ret = models.Person.objects.filter(pk__lte=3)  # lt  less than equal    小于等于
    
    ret = models.Person.objects.filter(pk__range=[1, 4])  # 范围
    ret = models.Person.objects.filter(pk__in=[1, 4])   # 成员判断
    ret = models.Person.objects.filter(name__in=['alexdsb','xx'])
    
    ret = models.Person.objects.filter(name__contains='x')   # contains 包含  like
    ret = models.Person.objects.filter(name__icontains='X')   # ignore contains 忽略大小写
    
    ret = models.Person.objects.filter(name__startswith='X')   # 以什么开头
    ret = models.Person.objects.filter(name__istartswith='X')   # 以什么开头
    
    ret = models.Person.objects.filter(name__endswith='dsb')   # 以什么开头
    ret = models.Person.objects.filter(name__iendswith='DSB')   # 以什么开头
    
    
    ret = models.Person.objects.filter(phone__isnull=False)   # __isnull=False  不为null
    
    ret = models.Person.objects.filter(birth__year='2020')
    ret = models.Person.objects.filter(birth__contains='2020-11-02')
    print(ret)
    

    188 0133 8917

    188 4321 2314

    186 2314 3200

    day62

    内容回顾

    ORM

    对象关系映射 面向对象和关系型数据库

    对应关系

    类 ——》 表

    对象 ——》 数据行(记录)

    属性 ——》 字段

    常用字段

    models.AutoField(primary_key=True)
    models.CharField(max_length) # 字符串 varchar(32)
    models.TextField  
    models.BooleanField  # 布尔值
    models.DateTimeField(auto_now=True)
    models.IntegerField  # 10  -21亿  + 21亿
    models.FloatField  
    models.DecimalField(max_digits=6,decimal_places=3)  # 10进制  999.999
    models.ForeignKey  
    models.ManyToManyField
    

    字段的参数

    null=True    数据库中该字段可以为空
    blank = True   form表单输入时允许为空
    default    默认值
    unique     唯一
    choices    可选的参数
    verbose_name  可显示的名字
    db_index 数据库索引
    db_column     列名
    editable  是否可编辑
    

    必知必会13条

    返回querySet

    all()      所有的对象
    filter()    获取满足条件的所有对象
    exclude()   获取不满足条件的所有对象
    order_by()   排序   - 
    reverse()   反转
    values()    [ {}  ]
    values_list()    [ ()  ]
    distinct()   去重  不能按照字段去重
    

    返回对象

    get()    获取有且唯一的对象
    first()
    last()
    

    返回数字

    count()
    

    返回布尔值

    exists()
    

    单表的双下划线

    字段__条件
    __gt   大于
    __gte   大于等于
    __lt  小于
    __lte   小于等于
    __in= []    成员判断
    __range = [3,6]  范围  3-6
    
    __contains =''    包含   like
    __icontains =''   忽略大小写
    
    __startswith =''   以什么开头
    __istartswith =''   以什么开头
    
    
    __endswith =''   以什么结尾
    __endswith =''   以什么结尾
    
    
    __year ='2019'  
    
    __isnull = True   字段值为null 
    

    外键

    # 基于对象的查询
    # 正向查询
    book_obj = models.Book.objects.get(pk=4)
    print(book_obj.name)
    print(book_obj.publisher)
    print(book_obj.publisher_id)
    
    # 反向查询
    pub_obj = models.Publisher.objects.get(pk=1)
    # 不指定related_name  表名小写_set
    print(pub_obj)
    print(pub_obj.book_set)   # 表名小写_set   关系管理对象
    print(pub_obj.book_set.all())
    
    # 指定related_name=‘books’  表名小写_set
    print(pub_obj.books)
    print(pub_obj.books.all())
    
    
    # 基于字段的查询
    # 查询“李小璐出版社”出版社的书
    ret = models.Book.objects.filter(publisher__name='李小璐出版社')
    
    # 查询“绿光”书的出版社
    # 没有指定related_name  表名小写
    ret = models.Publisher.objects.filter(book__name='绿光')
    
    # 指定related_name='books'
    ret = models.Publisher.objects.filter(books__name='绿光')
    
    # 指定related_query_name='book'
    ret = models.Publisher.objects.filter(book__name='绿光')
    
    print(ret)
    
    

    多对多

    # 基于对象的
    author_obj = models.Author.objects.get(name='yinmo')
    # print(author_obj.books)     # 关系管理对象
    # print(author_obj.books.all())  # 所关联的书
    
    book_obj = models.Book.objects.get(name='原谅你')
    # print(book_obj.author_set)
    # print(book_obj.author_set.all())
    
    # print(book_obj.authors)
    # print(book_obj.authors.all())
    
    # 基于字段的查询
    # print(models.Author.objects.filter(books__name='原谅你'))
    # print(models.Book.objects.filter(author__name='yinmo'))
    
    # all 查询所有的对象
    
    # set()  设置多对多的关系   [id,id]   [对象,对象]
    # author_obj.books.set([1,3])
    # author_obj.books.set(models.Book.objects.filter(pk__in=[2,4]))
    
    # add  新增多对多的关系   id,id   对象,对象
    # author_obj.books.add(1,3)
    # author_obj.books.add(*models.Book.objects.filter(pk__in=[1,3]))
    
    # remove  删除多对多的关系   id,id   对象,对象
    # author_obj.books.remove(1,3)
    # author_obj.books.remove(*models.Book.objects.filter(pk__in=[2,4]))
    
    # clear  删除所有多对多的关系
    # author_obj.books.clear()
    # author_obj.books.set([])
    
    # create  创建一个所关联的对象并且和当前对象绑定关系
    # ret = author_obj.books.create(name='yinmo的春天',publisher_id=1)
    # print(ret)
    
    pub_obj = models.Publisher.objects.get(pk=1)
    print(pub_obj.books.all())
    # print(pub_obj.books.set(models.Book.objects.filter(pk__in=[3,4])))
    # print(pub_obj.books.add(*models.Book.objects.filter(pk__in=[1])))
    
    # 外键的关系管理对象需要有remove和clear 外键字段必须可以为空
    # print(pub_obj.books.remove(*models.Book.objects.filter(pk__in=[1])))
    # print(pub_obj.books.clear())
    
    # print(pub_obj.books.create(name="你喜欢的绿色"))
    
    

    聚合和分组

    # 所有的价格
    
    # ret = models.Book.objects.all().aggregate(Sum('price'))
    # ret = models.Book.objects.all().aggregate(sum=Sum('price'),avg=Avg('price'),count=Count('pk'))
    # ret = models.Book.objects.filter(pk__in=[1,2]).aggregate(sum=Sum('price'),avg=Avg('price'),count=Count('pk'))
    
    # print(ret,type(ret))
    
    # 分组
    # 每一本书的作者个数
    ret = models.Book.objects.annotate(count=Count('author'))
    
    # 统计出每个出版社买的最便宜的书的价格
    # 方式一
    ret = models.Publisher.objects.annotate(Min('book__price')).values()
    # for i in ret:
    #     print(i)
    # 方拾二
    # ret = models.Book.objects.values('publisher__name').annotate(min=Min('price'))
    
    
    # 统计不止一个作者的图书
    
    ret = models.Book.objects.annotate(count=Count('author')).filter(count__gt=1)
    
    
    # 查询各个作者出的书的总价格
    
    ret = models.Author.objects.annotate(Sum('books__price')).values()
    
    print(ret)
    
    
    

    F和Q

    
    from django.db.models import F, Q
    
    ret = models.Book.objects.filter(sale__gt=F('kucun'))
    
    ret = models.Book.objects.all().update(publisher_id=3)
    
    ret = models.Book.objects.filter(pk=1).update(sale=F('sale')*2+43)
    
    # & 与  and
    # | 或  or
    # ~ 非  not
    # Q(pk__gt=5)
    ret = models.Book.objects.filter(Q(~Q(pk__gt=5) | Q(pk__lt=3)) & Q(publisher_id__in=[1, 3]))
    
    print(ret)
    
    
    

    事务

    from django.db import transaction
    
    
    try:
        with transaction.atomic():
            # 一系列的操作
            models.Book.objects.update(publisher_id=4)
            models.Book.objects.update(publisher_id=3)
            int('ss')
            models.Book.objects.update(publisher_id=2)
            models.Book.objects.update(publisher_id=5)
    
    except Exception as e:
        print(e)
    

    day63

    定义:

    ​ 保存在浏览器本地上的一组组键值对

    特性:

    	1. 服务器让浏览器进行设置的 
    
     		2. 下次访问时自动携带相应的cookie
    

    在django的操作:

    1. 获取

      request.COOKIES {}

      request.COOKIES[] .get

      request.get_signed_cookie(key,salt='...',default='xxx')

    2. 设置

      response.set_cookie(key,value)

      response.set_signed_cookie(key,value,salt='...')

    3. 删除cookie

      response.delete_cookie(key)

      from django.shortcuts import render, redirect, HttpResponse
      
      from functools import wraps
      
      
      # Create your views here.
      
      
      def is_loging(func):
          @wraps(func)
          def inner(request, *args, **kwargs):
              is_login = request.COOKIES.get('is_login')
              if is_login != 'true':
                           return redirect('/login/?indexUrl'.format(request.path_info))
                  
                  #request.path_info  帮助生成url
              ret = func(request, *args, **kwargs)
              return ret
      
          return inner
      
      
      def login(request):
          if request.method == 'POST':
              user = request.POST.get('user')
              pwd = request.POST.get('pwd')
      
              if user == 'alex' and pwd == 'alex3714':
                  # 保存登录状态  设置 cookie
                 returnUrl = request.GET.get('indexUrl')
                 ret = redirect( returnUrl if returnUrl else '/home/')
      
                  #获取GET请求中的url地址,有地址的返回url携带的地址,如果没有就走home地址
                  ret.set_cookie('is_login', 'true')
      
                  return ret
      
              return render(request, 'login.html', {'error': '用户名密码错误'})
      
          return render(request, 'login.html')
      
      
      @is_loging
      def home(request):
          return HttpResponse('这是home页面')
      
      

    session

    定义:

    ​ 保存在服务器上的一组组键值对,必须依赖cookie

    Django的使用:

    1. 设置

    ​ request.session[key] = value

    1. 获取

      request.session[key]

      request.session.get(key)

    2. 其他

      del request.session['k1']
      # 会话session的key
      request.session.session_key
      
      # 将所有Session失效日期小于当前日期的数据删除
      request.session.clear_expired()
      
      # 删除当前会话的所有Session数据
      request.session.delete()
        
      # 删除当前的会话数据并删除会话的Cookie。
      request.session.flush() 
      
      # 设置会话Session和Cookie的超时时间
      request.session.set_expiry(value)
          * 如果value是个整数,session会在些秒数后失效。
          * 如果value是个datatime或timedelta,session就会在这个时间后失效。
          * 如果value是0,用户关闭浏览器session就会失效。
          * 如果value是None,session会依赖全局session失效策略。
      

    session的配置

    from django.conf import global_settings

    cookie名字
    SESSION_COOKIE_NAME = 'sessionid'
    超时时间
    SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2
    每次请求保存session
    SESSION_SAVE_EVERY_REQUEST = False
    浏览器关闭session数据失效
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False
    存放session的位置
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'
    
    
    

    day64

    cookie和session

    1. 定义

      保存在浏览器上的一组组键值对

    2. 为什么要有?

      HTTP协议是无状态,每次请求之间都相互独立的,之间没有关系,没办法保存状态。

    3. 特性:

      1. 服务器让浏览器进行设置,浏览器有权利不保存
      2. 下次访问时,自动携带响应的cookie
      3. 保存在浏览本地的
    4. django的操作:

      1. 设置 set-cookie

        response.set_cookie(key,value,max_age=5,path='/')

        response.set_signed_cookie(key,value,max_age=5,path='/',salt='xxxxx')

      2. 获取 cookie

        request.COOKIES {}

        request.COOKIES[key] request.COOKIES.get(key)

        request.get_signed_cookie(key,salt='xxxxx',default=‘’)

      3. 删除 set-cookie

        response.delete-cookie(key')

    session

    1. 定义:

      ​ 保存在服务器上的一组组键值对,必须依赖cookie

    2. 为什么要有?

      1. cookie保存在浏览器上,不太安全
      2. 浏览器对cookie的大小有一定的限制
    3. session的流程:

      1. 浏览器发送请求,没有cookie也没有session
      2. 要设置session时,先根据浏览器生成一个唯一标识(session_key),存键值对,并且有超时时间
      3. 返回cookie session_id = 唯一标识
    4. 在django中的操作:

      1. 设置

        request.session[key] = value

      2. 获取

        request.session[key] request.session.get()

      3. 删除

        del request.session[key]

        request.session.pop(key)

        request.session.delete() 删除所有的session 不删除cookie

        request.session.flush() 删除所有的session 删除cookie

      4. 其他

        request.session.clear_expired() 删除已经失效的session数据

        request.session.set_expiry(value)

      5. 配置

        from django.conf import global_settings

      ​ SESSION_SAVE_EVERY_REQUEST = True 每次请求都更新session数据

      ​ SESSION_EXPIRE_AT_BROWSER_CLOSE = True

      ​ SESSION_ENGINE = 'django.contrib.sessions.backends.db' 默认存在数据库

      ​ 缓存 文件 缓存+数据库 加密cookie

      ​ Json序列化的过程

    中间件

    中间件 :中间件就是一个类,在全局范围内处理django的请求和响应。

    类 5个方法 4个特点

    规律:
        
    #在你视图函数之前执行的这些方法按照顺序执行,
    
    #在视图函数执行之后的这些方法按照倒序执行
    

    process_request(self,request)

    执行时间:

    ​ 在视图函数之前

    执行顺序:

    ​ 按照注册的顺序 顺序执行

    参数 :

    ​ request: 请求的对象,和视图函数是同一个

    返回值:

    ​ None : 正常流程

    ​ HttpResponse:之后中间件的process_request、路由、process_view、视图都不执行,执行执行当前中间件对应process_response方法,接着倒序执行之前的中间件中的process_response方法。

    中间件--> 浏览器发送请求回复响应,之前是在视图里回复响应的,写到中间件里会响应,后面要做的事就不用做了!
    

    process_response(self, request, response)

    执行时间:

    ​ 在视图函数之后

    执行顺序:

    ​ 按照注册的顺序 倒序执行

    参数 :

    ​ request: 请求的对象,和视图函数是同一个

    ​ response: 响应对象

    返回值:

    ​ HttpResponse: 必须返回

    返回值可以是别人传过来的response 
    也可以自己返回	HttpResponse
    

    process_view(self, request, view_func, view_args, view_kwargs)

    执行时间:

    ​ 在路由匹配之后,在视图函数之前

    执行顺序:

    ​ 按照注册的顺序 顺序执行

    参数 :

    ​ request: 请求的对象,和视图函数是同一个

    ​ view_func:视图函数

    ​ view_args: 给视图传递的位置参数

    ​ view_kwargs: 给视图传递的关键字参数

    返回值:

    ​ None: 正常流程

    ​ HttpResponse: 之后中间件的process_view、视图都不执行,直接执行最后一个中间件process_response,倒序执行之前中间件的process_response方法

    process_exception(self, request, exception)

    执行时间:

    ​ 在视图函数出错之后执行

    执行顺序:

    ​ 按照注册的顺序 倒序执行

    参数 :

    ​ request: 请求的对象,和视图函数是同一个

    ​ exception:报错的对象

    返回值:

    ​ None: 自己没有处理,交给下一个中间件处理,所有的中间件都没有处理,django处理错误。

    ​ HttpResponse: 之后中间件的process_exception,直接执行最后一个中间件process_response,倒序执行之前中间件的process_response方法

    process_template_response(self,request,response)

    执行时间:

    ​ 当视图函数返回一个TemplateResponse对象

    执行顺序:

    ​ 按照注册的顺序 倒序执行

    参数 :

    ​ request: 请求的对象,和视图函数是同一个

    ​ response:响应的对象

    返回值:

    ​ HttpResponse: 必须返回

    day65

    Ajax

    js的技术,就是发请求接受响应的技术,传输少量的数据。

    发请求的途径:

    1. a标签 get
    2. 地址栏输入地址 get
    3. form表单 get / post

    特点:

    1. 局部刷新

    2. 传输的数据量少

    3. 异步

    简单使用:

    $.ajax({
                'url':'/calc/',
                'type':'post',
                'data':{
                    'k1':$('[name="i1"]').val(),
                    'k2':$('[name="i2"]').val(),
                },
                success:function (ret) {
                   $('[name="i3"]').val(ret)
                }
            })
    

    参数

    $.ajax({
                url: '/test/',   	#  提交的地址
                type: 'post',		#  请求方式
                data: {				#  提交的数据
                    name: 'alex',
                    age: 73,
                    hobby: JSON.stringify(['装逼', '画饼', '上过北大'])
                },
                success: function (ret) {		# 响应成功的回调函数
    
                },
                error:function (ret) {			# 响应失败的回调函数
                    console.log(ret)
                }
            })
    

    上传文件

    $('button').click(function () {
    
            var form_data = new FormData();
            form_data.append('k1','v1');
            form_data.append('f1',$('#f1')[0].files[0]);
    
            $.ajax({
                url :'/file_upload/',
                type:'post',
                data:form_data,  // { k1:v1 }
                processData: false,  //   不需要处理数据
                contentType: false,  //   不需要contentType请求头
                success:function (ret) {
                    console.log(ret)
                }
    
            })
    
        })
    

    ajax能通过django的csrf的校验:

    前提必须有cookie:

    1. {% csrf_token %}

    2. 给视图加装饰器

      from django.views.decorators.csrf import ensure_csrf_cookie
      
      @ensure_csrf_cookie
      def index(request):
      

    方式一:data中添加键值对 csrfmiddlewaretoken

    $.ajax({
                'url': '/calc/',
                'type': 'post',
                'data': {
                    'csrfmiddlewaretoken': $('[name="csrfmiddlewaretoken"]').val(),
                    'k1': $('[name="i1"]').val(),
                    'k2': $('[name="i2"]').val(),
                },
                success: function (ret) {
                    $('[name="i3"]').val(ret)
                }
            })
    

    方式二:加请求头 x-csrftoken

    $('#b2').click(function () {
            // 点击事件触发后的逻辑
            $.ajax({
                'url': '/calc2/',
                'type': 'post',
                headers:{'x-csrftoken':$('[name="csrfmiddlewaretoken"]').val(),},
                'data': {
                    'k1': $('[name="ii1"]').val(),
                    'k2': $('[name="ii2"]').val(),
                },
                success: function (ret) {
                    $('[name="ii3"]').val(ret)
                }
            })
    
        })
    

    方式三:

    导入文件

    day66

    内容回顾

    ajax

    js技术,发请求。

    特点:

    1. 异步

    2. 局部刷新

    3. 数据量小

    发请求的方式:

    1. 地址栏输入地址 get
    2. a标签 get
    3. form get /post
      1. action 提交的地址 method='post' 上传的文件的 enctype="multipart/form-data"
      2. 有button或者 input类型submit
      3. input 标签有name属性 有的需要有value
    4. ajax

    简单使用:

    使用jq发送ajax请求

    $.ajax({
        url:'' ,  //  请求发送的地址
        type:'post',   //  请求方式
        data: {} ,  //  数据
        success:function (res){}      //  响应成功之后执行的回调函数  res返回的响应体 
        
    })
    

    上传文件

    var form_data  =  new FormData()
    form_data.append('k1','v1')
    form_data.append('f1',$('#f1')[0].files[0])
    
    $.ajax({
        url:'' ,  //  请求发送的地址
        type:'post',   //  请求方式
        data:form_data ,  //  数据
        processData:false,   //  不需要处理数据的编码 multipart/form-data
        contentType:false,   //  不需要处理contentType的请求头
        success:function (res){}      //  响应成功之后执行的回调函数  res返回的响应体 
        
    })
    
    

    ajax通过django的csrf的校验

    前提:必须要有csrftoken的cookie

    方式一:

    给data添加csrfmiddlewaretoken键值对

    方式二:

    给headers 添加 x-csrftoken的键值对

    方式三:

    导入文件

    csrf相关装饰器

    from django.views.decorators.csrf import ensure_csrf_cookie,csrf_exempt,csrf_protect
    
    # ensure_csrf_cookie  确保有cookie
    # csrf_exempt   不需要进行csrf的校验
    # csrf_protect  需要进行csrf的校验
    
    注意:  csrf_exempt CBV的时候只能加载dispatch方法上
    

    今日内容

    form组件

    form

    1. 有input让用户输入
    2. 提交数据

    form组件

    1. 提供input框
    2. 能对数据做校验
    3. 返回错误提示

    定义:定义是在views.py中

    from django import forms
    class RegForm(forms.Form):
        username = forms.CharField(label='用户名')
        password = forms.CharField(label='密码')
    

    使用:

    函数
    def register2(request):
        if request.method == 'POST':
            form_obj = RegForm(request.POST)
    
            if form_obj.is_valid():  # 校验数据
                # 插入数据库
                print(form_obj.cleaned_data)
                print(request.POST)
    
                return HttpResponse('注册成功')
        else:
            form_obj = RegForm()
        return render(request, 'register2.html', {'form_obj': form_obj})
    
    
    模板
    {{ form_obj.as_p }}   # 展示所有的字段
    
    {{ form_obj.username }}           #  生成input框
    {{ form_obj.username.label }}     #  中文提示
    {{ form_obj.username.id_for_label }}    # input框的id
    {{ form_obj.username.errors }}     # 该字段的所有的错误
    {{ form_obj.username.errors.0 }}    # 该字段的第一个的错误
    
    {{ form_obj.errors }}    # 该form表单中所有的错误
    
    

    常用字段:

    CharField      # 文本输入框
    ChoiceField    # 单选框
    MultipleChoiceField  # 多选框
    

    字段参数:

        required=True,               是否必填
        widget=None,                 HTML插件
        label=None,                  用于生成Label标签或显示内容
        initial=None,                初始值
        error_messages=None,         错误信息 {'required': '不能为空', 'invalid': '格式错误'} 
        disabled=False,              是否可以编辑
        validators=[],               自定义验证规则
    
    
    

    校验

    自定义校验规则

    1. 写函数

      from django.core.exceptions import ValidationError/校验
      
      def checkusername(value):
      	# 通过校验规则  什么事都不用干
      	# bu通过校验规则  抛出异常ValidationError
          if models.User.objects.filter(username=value):
              raise/抛出异常/ ValidationError('用户名已存在')
              
      username = forms.CharField(
      
              validators=[checkusername,])
      
      

    1. 用内置的校验器

      from django.core.validators import RegexValidator
      
      phone = forms.CharField(min_length=11,max_length=11,validators=[RegexValidator(r'^1[3-9]d{9}$','手机号格式不正确')])
      
      
      

    局部钩子和全局钩子(推荐使用)

        def clean(self):
            # 全局钩子
            # 通过校验   返回self.cleaned_data
            # 不通过校验   抛出异常
            password = self.cleaned_data.get('password')
            re_password = self.cleaned_data.get('re_password')
            if password == re_password:
                return self.cleaned_data
            else:
                self.add_error('password','两次密码不一致!!')
                raise ValidationError('两次密码不一致')
    
        def clean_username(self):
            # 局部钩子
            # 不通过校验   抛出异常
             # 通过校验   返回当前字段的值
            value = self.cleaned_data.get('username')
            #获取存放有效数据的那些字典找他得值
            if models.User.objects.filter(username=value):
                raise ValidationError('用户名已存在')
            return value
    
    

    局部钩子

    #小点:
    自定义的函数校验器,需要填红色的框框,也是针对于某一个字段,别的字段要用,就得加validators=[自定义校验器函数]
    
    form组件,局部钩子,只针对于某一个字段进行校验
    上面这个局部钩子只是正对于username这个字段进行的校验!
    

    day67

    django web框架

    功能

    1. socket收发消息 wsgi
    2. 根据不同的路径返回不同的内容
    3. 返回动态页面(字符串的替换 模板的渲染)

    在浏览器上的地址输入地址回车会发生什么事情?

    HTTP协议

    超文本传输协议 规定请求和响应的格式

    请求(浏览器发送给服务器的消息 request)

    格式:

    '请求方式 URL路径 HTTP/1.1

    K1: v1

    k2: v2

    请求体(请求数据)' // get方法没有请求体

    响应(服务器返回给浏览器的消息 response)

    格式

    ‘HTTP/1.1 状态码 状态描述

    K1: v1

    k2: v2

    响应体(响应数据)’

    请求方式:8种 GET POST PUT DELETE HEAD OPTION TRACE CONNECT

    状态码:

    1xx 请求已经接受 还需要进一步的处理

    2xx 请求正常接受并且响应

    3xx 重定向 301 302

    4xx 请求的错误 403 404 402

    5xx 服务器的错误 500 502

    头:

    location 重定向

    cookie set-cookie

    x-csrftoken

    content-type text/html applicaton/json

    user-agent

    host

    url地址:

    https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu

    http 80

    https 443

    django

    路由

    URL地址和函数的对应关系

    URLconf

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^publisher/(d+)/$',views.register ),
        url(r'^register2/$',views.register2 ),
    ]
    

    正则表达式

    ^ $ d w  ? + * . |
    

    分组和命名分组

    捕获参数 ?id=1111

    分组 () 按照位置传参 传给视图

    命名分组 (?P ) 按照关键字传参 传给视图

    路由分发 include

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^app01/',include('app01.urls') ),
    ]
    

    app01 urls.py

    urlpatterns = [
        url(r'^register2/$',views.register2 ),
    ]
    

    URL的命名和反向解析

    静态路由

    命名

        url(r'^register2/$',views.register2,name='reg' ),
    

    反向解析

    模板

     {% url 'reg' %}   #   '/app01/register2/'
    

    py文件

    from django.urls  import reverse
    reverse('reg')   #   '/app01/register2/'
    

    分组

    命名

     url(r'^register(d+)/$',views.register2,name='reg' ),
    

    反向解析

    模板

     {% url 'reg' 20  %}   #   '/app01/register20/'
    

    py文件

    from django.urls  import reverse
    reverse('reg',args=('30',))   #   '/app01/register30/'
    

    命名分组

    命名

     url(r'^register(?P<pk>d+)/$',views.register2,name='reg' ),
    

    反向解析

    模板

     {% url 'reg' 20  %}   #   '/app01/register20/'
     {% url 'reg' pk=20  %}   #   '/app01/register20/'
    

    py文件

    from django.urls  import reverse
    reverse('reg',args=('30',))   #   '/app01/register30/'
    reverse('reg',kwargs={‘pk’:'30'}   #   '/app01/register30/'
    

    namespace

    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^app01/',include('app01.urls',namespace='app01') ),
        url(r'^app02/',include('app02.urls',namespace='app02') ),
    ]
    

    反向解析

    {% url 'app01:reg' 20 %}

    reverse('app01:reg',args=('30',))

    视图

    MVC

    MTV

    view 逻辑 接受请求返回响应

    FBV CBV

    def xxx(request,*args,**kwargs):
    	# 逻辑
    	return response
    
    url(r'^xxx/',xxx ),
    
    from django.views import View
    class Class(View):
    
    	def get(self,request,*args,**kwargs):
            # 处理get请求的逻辑
            self.request
    		return response
        
        def post(self,request,*args,**kwargs):
            # 处理post请求的逻辑
    		return response
    
    url(r'^xxx/',Class.as_view()),
    

    加装饰器

    from django.utils.decorators import method_decorator
    
    1. 加在方法上

      @method_decorator(timer)
      def get(self,request,*args,**kwargs):
      
    2. 加在类上

      @method_decorator(timer,name='get')
      @method_decorator(timer,name='post')
      class Class(View):
      
    3. 加在dispatch

      @method_decorator(timer,name='dispatch')
      class Class(View):
      

    request

    request.POST    #  POST提交的数据 {}    urlencode编码
    request.GET     #   url上携带的参数  ?id=1  {id:1}
    request.method  #  请求方法  GET POST
    request.path_info  # 路径信息  不包含IP和端口 也不包含查询参数
    request.FILES   # 上传的文件 enctype='form-data'
    request.session  # {}  session 
    request.COOKIES  # cookie  
    request.META   # 请求头的信息  HTTP_  小写——》  大写  - ——》 _
    request.body  # 请求体  原始数据
    
    request.get_full_path()  #  完整的路径信息 不包含IP和端口 包含查询参数
    request.is_ajax()  # 是否是ajax请求
    request.get_signed_cookie(key,salt,defalut='')
    

    response

    HttpResponse('字符串')   #  字符串
    JsonResponse({})   JsonResponse([],safe=False) 
    render(request,'模板文件的路径',{})   # 返回页面 已经替换好了
    redirect('地址或者URLname')   # 重定向  响应头Location:地址 301 302 
    TemplateResponse(request,'模板文件的路径',{})  # 后续在调用render方式进行渲染
    

    模板

    html + 特殊的语法

    变量

    {{ }} 变量 {% %}

    .key .属性 .方法 .索引

    过滤器

    内置过滤器

    safe default filesizeformat date:'Y-m-d H:i:s' add length slice:'::' join

    标签

    for forloop

    for ... empty

    if

    不支持算数运算 连续判断

    母版和继承

    母版:

    1. 写上一个HTML页面,包含多个页面的公共部分
    
    2. 定义多个block块,让子页面进行重写
    

    继承:

    1. {% extends '母版的路径' %}
    
    2. 重写block块
    

    组件

    一段HTML代码 ——》 文件 nav.html

    页面 {% include ‘nav.html’ %}

    静态文件

    {% load static %}

    {% static '相对路径' %}

    {% get_static_prefix %} # STATIC_URL ='/static/'

    自定义的方法

    filter、simple_tag 、inclusion_tag

    定义:

    1. 在已经注册的APP下创建templatetags的python包;

    2. 在python包中创建py文件(自己定义my_tags)

    3. 写代码

      from  django import template
      register = template.Library() 
      
    4. 写函数 +加装饰器

      @register.filter
      def add_arg(value,arg):
      	return 'xxxx'
      
      
      @register.simple_tag
      def joins(*args,**kwargs):
      	return 'xxxxxxx'
      
      
      @register.inclusion_tag('li.html')
      def show_li(*args,**kwargs):
      	return {'li':[1,2]}
      
      li.html
      {% for i in li %}
      	{{ i }}
      {% endfor %}
      
      

    使用:

    模板

    {% load my_tags %}
    
    {{ a|add_arg:'xxx' }}   # 'xxxx'
    
    {% joins 'v1' 'v2' k1='v3' k2='v4'  %}  # 'xxxxxxx'
    
    {% show_li 3 %}   #  1 2 
    

    ORM

    对象关系映射

    对应关系

    类 ——》 表

    对象 ——》 数据行(记录)

    属性 ——》 字段

    必知必会13条

    返回对象列表 QuerySet

    all

    filter

    exculde

    values 【{}】

    values_list 【() 】

    order_by()

    reverse()

    distinct 去重

    返回对象

    get

    first

    last

    返回布尔值

    exists

    返回数字

    count

    单表的双下划线

    __gt 大于
    __gte 大于等于
    __lt  小于
    __lte   小于等于
    __in= []   在不在成员判断
    __range = [1,6]   范围
    __startswith  以什么开头 __istartswith  以什么开头
    __endswith  以什么结尾 __iendswith  以什么结尾
    __contains  包含 like __icontains 
    __year   年
    __isnull=True 
    

    外键的操作

    class Book(models.Model):
    	name= models.CharField(max_length=32)
    	pub= models.ForginKey(to='Publisher',on_delete=models.CASCADE,related_name='books')
    

    基于对象

    正向
    book_obj.pub      ——》 关联的出版社对象
    book_obj.pub_id   ——》 关联的出版社对象id
    反向
    不指定 related_name
    pub_obj.book_set        ——》 关系管理对象
    pub_obj.book_set.all()  ——》 关联的所有的书籍对象  表名_set 
    指定related_name='books'
    pub_obj.books.all()  ——》 关联的所有的书籍对象  related_name
    

    基于字段

    models.Book.objects.filter(pub__name='xxx')
    models.Publisher.objects.filter(book__name)  不指定 related_name
    models.Publisher.objects.filter(books__name)  指定 related_name='books'
    

    多对多

    class Book(models.Model):
    	name= models.CharField(max_length=32)
    	
    class Author(models.Model):
    	name= models.CharField(max_length=32)
    	books= models.ManyToManyField('Book',related_name='authors')
    

    all()

    set([]) [对象,对象] [id,id ]

    add()

    remove()

    clear()

    create()

    聚合和分组

    from django.db.models import  Max,Min,Count,Avg,SumHobby.objects.all().aggregate(max=Max('filed'))  # {max:'xxx'  }
    
    Author.objects.annotate(count=Count('books'))  # 对象列表
    
    Book.objects.values('authors__name').annotate(Min('price'))   # [{}]
    

    F和Q

    Book.objects.update(price=F('price')+2)
    
    Q(Q(price__gt=10)|Q()) 
    | 或
    & 与
    ~ 非
    

    事务

    一系列的操作 要么都成功,要么都失败。

    from django.db import transaction
    
    try:
        with transaction.atomic():
            # 一系列操作
            pass
    
    except Exception as e:
        print(e)
    

    中间件

    处理django请求和响应的框架级别的钩子。

    5个方法 4个特征

    cookie和session

    为什么要有cookie?

    定义:保存在浏览器上一组组键值对

    特点:

    1. 由服务器让浏览器进行设置
    
    2. 保存在浏览器本地的
    3. 下次访问时自动携带对应的cookie
    

    django中的操作:

    1. 设置 set-cookie

      response.set_cookie(key,v,max-age=5,path='/')
      
    2. 获取

      request.COOKIES[]  get()
      
    3. 删除 set-cookie

      response.delete_cookie(key)
      

    session

    为什么要有session?

    定义:保存在服务器上一组组键值对,必须依赖cookie

    django中的操作:

    1. 设置

      request.session[key] = value

    2. 获取

      request.session[key] request.session.get(key)

    3. 删除

      del request.session[key]

      request.session.pop(key)

      request.session.delete()

      request.session.flush()

      request.session.clear_expired() # 删除已经过期的数据

    4. request.session.set_expiry()

    配置

    ​ 引擎 SESSION_ENGINE 位置 数据库 缓存 文件 缓存+数据库 加密cookie

    ​ SESSION_SAVE_EVERY_REQUEST = True

    ​ SESSION_EXPIRE_AT_BROWSER_CLOSE = True

    ​ json序列化

    ajax

    js技术 ,发请求。

    $.ajax({
        url: 地址,
        type:  请求方式,
        data : {},
        success:function (res){  
            # 逻辑
            $(this)
        }
        
    })
    
    
    $.ajax({
        url: 地址,
        type:  请求方式,
        data : {},
        success: (res) => {  
            # 逻辑
            $(this)
        }
        
    })
    

    ajax通过django的csrf的校验

    1. 给data 加 { ’csrfmiddlewaretoken‘: }
    2. 加请求头 x-csrftoken

    form

    功能:

    1. 提供input框
    2. 校验forms
    3. 错误提示
    from django import forms
    class RegForm(forms.Form):
        name  = forms.CharField(widget=)
        
        def clean_字段名(self):
            # 校验规则
            # 通过校验  返回当前字段的值
        	# 不通过校验  抛出异常  
        
        def clean(self):
            # 校验规则
            # 通过校验  返回所有字段的值self.cleaned_data
        	# 不通过校验  抛出异常   __all__   self.add_error('字段',’错误信息‘)
    
    label 	中文提示
    initial  初始值
    required  必填
    error_messages = { }   
    disabled  
    validators 校验器 
    

    视图

    form_obj = RegForm()
    
    
    form_obj = RegForm(request.POST)
    form_obj.is_valid()  
    form_obj.cleaned_data  通过校验的数据
    
    

    模板

    {{ form_obj.as_P }}
    
    {{ form_obj.name }}          input框
    {{ form_obj.name.label }}     中文提示
    {{ form_obj.name.id_for_label }}     input框的id
    {{ form_obj.name.errors }}    当前字段的所有错误
    {{ form_obj.name.errors.0 }}  当前字段的第一个错误
    
    {{ form_obj.errors }}    所有字段的所有错误
    
    

    校验顺序

    每个字段:

    ​ 内置校验规则 field.validate(必填 长度 )

      校验器field.run_validators(默认校验器,自定义的校验器) 
    

    ​ 局部钩子form_obj.clean_字段名

    全局钩子 orm_obj.clean

  • 相关阅读:
    对于EMC DAE、DPE、SPE、SPS的解释
    linux用户添加组
    do_group_exit函数
    bpf移植到3.10
    网络中的GSO分段,整个tcp/ip协议栈中都哪里发生了分段
    发送tcp的时候,数据包是如何拷贝的
    安装llvm
    怎么打印lua的函数调用栈
    调度的log 1.5ms 12ms 4ms
    显示两个文本的差异:强大的grep
  • 原文地址:https://www.cnblogs.com/zgboy/p/12421941.html
Copyright © 2011-2022 走看看