zoukankan      html  css  js  c++  java
  • Django 笔记整理

    自写框架

    HTTP协议

    http协议:
       即超文本传输协议(Hypertext transfer protocol)。是一种详细规定了浏览器和万维网(WWW = World Wide Web)服务器之间互相通信的规则,通过因特网传送万维网文档的数据传送协议
    客户端发送一个HTTP请求到服务器的请求消息包括以下格式:
      请求行、请求头部、空行和请求数据四个部分组成
    特性:
       基于TCP/IP协议;无状态;短链接;被动响应

     

    wsgiref模块

    WSGI(Web Server Gateway Interface)是一种规范,它定义了使用python编写的web app(应用程序)与web server(socket服务端)之间接口格式,实现web app与web server间的解耦。通俗的说:当规范建立后,程序就不再重复编写web server(socket服务端),而是直接使用现成的实现WSGI的模块(例如:wsgiref、uwsgi、werkzeug),从而让程序员更加专注与业务代码与其重复造轮子,不如直接用现成的。

    Python的wsgiref是基于WSGI规范封装的模块,我们可以在这个模块基础上开发我们的web server


    from wsgiref.simple_server import make_server

    def login():
    pass

    def error():
    return "404 error"

    urls = [
    ("/login",login)
    ]

    def run(environ,response):
    # environ:请求数据封装成格式为字典
    path = environ.get('PATH_INFO')   # 获取请求的url
    # 返回数据的格式(响应行,请求头)
    response("200 OK",[('Content-Type','text/html; charset=utf-8')])

    func = 0
    for i in urls:
    if path == i[0]:
    func = i[1]
    break
    if func:
    res = func()
    else:
    res = error()

    # 返回给客户端的消息
    return [res.encode("utf-8")]

    # 绑定host,port 自动执行 run函数
    s = make_server("0.0.0.0",9000,run)

    # 启动服务端,循环监听
    s.serve_forever()

    动态网页

    import time
    from wsgiref.simple_server import make_server

    def gen():
    with open(r"..1.html","r",encoding='utf-8') as f:
    data = f.read()
    t = time.ctime()
    data = data.replace("time",t)
    return data


    def error():
    return "404 error"

    urls = [
    ("/",gen)
    ]

    def run(environ,response):
    # environ:请求数据封装成格式为字典
    path = environ.get('PATH_INFO')   # 获取请求的url
    # 返回数据的格式(响应行,请求头)
    response("200 OK",[('Content-Type','text/html; charset=utf-8')])

    func = 0
    for i in urls:
    if path == i[0]:
    func = i[1]
    break
    if func:
    res = func()
    else:
    res = error()

    # 返回给客户端的消息
    return [res.encode("utf-8")]

    # 绑定host,port 自动执行 run函数
    s = make_server("127.0.0.1",9000,run)

    # 启动服务端,循环监听
    s.serve_forever()

    模板语法jinja2

    from jinja2 import Temlate

    # html部分
    {{user}}

    # 后端部分
    from wsgiref.simple_server import make_server
    from jinja2 import Template

    def gen():
    dic = {"name":"bajie","age":18}
    with open(r"..1.html","r",encoding='utf-8') as f:
    data = f.read()
    t = Template(data)
    data = t.render(user=dic)
    return data

    def error():
    return "404 error"
    urls = [
    ("/",gen)
    ]

    def run(environ,response):
    # environ:请求数据封装成格式为字典
    path = environ.get('PATH_INFO')   # 获取请求的url
    # 返回数据的格式(响应行,请求头)
    response("200 OK",[('Content-Type','text/html; charset=utf-8')])

    func = 0
    for i in urls:
    if path == i[0]:
    func = i[1]
    break
    if func:
    res = func()
    else:
    res = error()

    # 返回给客户端的消息
    return [res.encode("utf-8")]
    # 绑定host,port 自动执行 run函数
    s = make_server("127.0.0.1",9000,run)
    # 启动服务端,循环监听
    s.serve_forever()

    Django

    # 创建项目(先进入到要创建项目的文件夹)
    django-admin startproject 项目名

    # 创建应用(app)
    python manage.py startapp 应用名称

    # 启动应用
    python manage.py runserver IP/port

    项目目录结构

    项目
    应用
      migrants
          __init__.py
           __init__.py
           admin.py               # 数据库后台
           apps.py                # django 把项目和app 关联文件
           models.py              # 数据库操作
           tests.py               # 单元测试
           views.py               # 视图函数,业务逻辑
          HttpResponse(字符串)
               render(request,xxx.html)
       项目文件
      __init__.py
           setting.py             # 程序的配置文件
           urls.py                # 程序的路由系统(url与视图函数的对应关系)
           swgi.py                # 指定框架的wsgi
       
       templates                  # html模板文件自己创建
       db.sqlite3
       manage.py                  # 管理程序文件,启动与结束等

    MVC&MTV架构

    # MVC 是一种使用MVC (Model View Controller 模型-视图逻辑-控制器) 设计创建的Web的模式

     

    # MTV
    (Model templates Controller 模型-视图逻辑-控制器) 设计创建的Web的模式

     

    1, url 路由层

    1,正则匹配
    APPEND_SLASH = False    取消自动加/
       url(r'login',view.login)
       url(r'longing',view.longing)    
    2,匹配首页
    url(r"^$",view.home)
    3,尾页匹配
    url(r"",view.error)

     

    1.1 静态路由

    url('login/(^2020$)/', views.login)

    2.0
    url('login/2020/', views.login)

    视图函数(位置传参)

    1.2 动态路由

    re_path('login/(?P<year>[0-9]{4})', views.login)  # 视图函数(关键字传参year)

    re_path('login/(?P<slug>[w-]+)', views.login)    # 匹配任意字符


    2.0
    path('login/(<int:year>)', views.login)  # 视图函数(关键字传参year)

    path('login/<slug:slug>', views.login)    # 匹配任意字符

    1.3路由分发(include)与名称空间(了解)

    # 不同应用相同url的分发
    '''
    如果view方法相同时,反向解析不能识别前缀url,这时需要使用namespace命名空间,
    解析时:reverse(app01:home)  
    '''
    ### 主文件下的urls文件
    from django.conf.urls import url,include
    from django.contrib import admin

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

    ### 应用app01的urls文件
    from django.conf.urls import url
    from app01 import views

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

    ### 应用app02的urls文件
    from django.conf.urls import url
    from app02 import views

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

    # 注意事项:总路由不能加$

    # 访问路径
    http://127.0.0.1:8000/app01/home/
    http://127.0.0.1:8000/app02/home/

    1.4 url 反向解析

    from django.shortcuts import reverse

    1,先给路由起一个别名
    url(r'^func/',view.func,name='别名')
    2,后端view反向解析
    print(reverse('别名'))
    3,前端html反向解析
    <a href = "{% url 别名 %}">ooo</a>

    # 无名分组反向解析(数据的主键值来替代1)
    url(r'^func/( d+)',view.func,name='别名')
    1,后端view反向解析
    print(reverse('别名',args=(1,)))
    2,前端html反向解析
    <a href = "{% url 别名 1 %}">ooo</a>

    # 有名分组反向解析
    url(r'^func/(?P<year> d+)',view.func,name='别名')
    1,后端view反向解析
    print(reverse('别名',args=(1,)))      简写!
    print(reverse('别名',kwargs={'year':1}))
    2,前端html反向解析
    <a href = "{% url 别名 1 %}">ooo</a>  简写!
    <a href = "{% url 别名 year = 1 %}">ooo</a>

    2, views(视图层)

    # request对象方法





     

    2.1 FBV模式

    url(r'^longin/(/d+)', views.longin)

    def longin(request,参数1(/d+)):
       return  render(request,"longin.html")

    返回页面:
       HttpResquest("hellow word")                                 # 返回字符串
       render(request,"xx.html",{jinjia2传值})                      # 返回页面
       redirect("网址")                                             # 重定向
       JsonResponse(数据,json_dumps_params={"ensure_ascii":False})  # 返回json格式数据
      默认只能序列化字典,序列化其他加参数  JsonResponse(数据,json_dumps_params={"ensure_ascii":False},safe=False)    # 返回前端是对象

    2.2 CBV模式

    url(r'^longin/', views.Select.as_view())

    from django.views import View

    class Select(View,):
       def dispatch(self, request, *args, **kwargs):
           print('第一次执行位置')
           res = super().dispatch(request, *args, **kwargs)
           print('第三次执行位置')
           return res   # 按照不同的方法,执行后的返回值返回到页面

       def get(self, request):
           print('第二次执行位置')
           return HttpResponse("get请求方法")

       def post(self, request):
           pass

    3,templates渲染层

    3.1 万能点

    # (索引,key,属性,方法(不加括号,只能进行无参数方法),类,对象)

    3.2 过滤器

    # html,语法:{{ value|filter_name:参数}}
    {{ value|default:"默认值"}}                    # 当value没有传值时,拿默认值填充
    {{ value|length}}                             # value的长度
    {{ value|filesizeformat}}                     # 数字可转换为MB单位
    {{ value|slice:"0:4"}}                        # value切片
    {{ value|date:"Y-m-d H:i:s" }}                # value时间格式化
    {{ value|safe }}                              # 若果是标签格式,具有标签效果
    {{ value|truncatechars:4 }}                   # 从第四个字符截断...
    {{ value|truncatewords:4 }}                   # 从第四个单词截断...
    {{ value|cut:' ' }}                           # 移除(字符)空格  
    {{ value|join:'-' }}                          # 字符串拼接

    3.3 模板标签

    3.3.1 for 标签

    {for i in lst}
    <h1>i</h1>
    如果lst为空,或者后台没有给lst数据,那么就展示empty下面的内容
    {% empty %}  
    <span>哥,啥也木有啊</span>
    {% endfor %}

    ### forloop

    forloop.counter            当前循环的索引值(从1开始),forloop是循环器,通过点来使用功能
    forloop.counter0           当前循环的索引值(从0开始)
    forloop.revcounter         当前循环的倒序索引值(从1开始)
    forloop.revcounter0        当前循环的倒序索引值(从0开始)
    forloop.first              当前循环是不是第一次循环(布尔值)
    forloop.last               当前循环是不是最后一次循环(布尔值)
    forloop.parentloop         本层循环的外层循环的对象,再通过上面的几个属性来显示外层循环的计数等

    3.3.2 if 标签(可以配合过滤器使用)

    {% if 条件 %}

    {% elif 条件 %}

    {% else %}
    {% endif %}

    3.4 模板导入(组件)

    导入组件
    {% include '组件.html' %}

    3.5 静态文件配置

    # 静态文件:拿来就可以使用的(img,css,js...)
    将html文件放到templates文件夹下
    1,在项目根目录下创建statics文件夹(img,css,js,other)

    2,在settings.py文件中设置如下内容

    STATIC_URL = '/static/'        # 路径别名
    STATICFILES_DIRS = [os.path.join(BASE_DIR,'statics'),]    # 找到static_file 路径这里

    引入方式一:
       1,<link rel="stylesheet" href="/static/img/static_file.img">
       2,{% load static %}
         <link rel="stylesheet" href="{% static /static_file.img %}">
       
    3,<img src="/static/img/1.png" alt="">    # img标签路径设置

    3.6 模板继承

    # 模板(母版.html页面)

    划分子板可能要添加内容的区域
    {% block content%}
    要添加内容的区域
    {% endblock %}

    # 继承模板
    {% extends '母版.html页面'%}

    {% block content%}
    子板要修改的内容
    {% endblock %}

    # 总结:
    {% block css%}  等同样适用

    4,ORM(Object Relational Mapping)

    # 链接数据库
    1,创建库
    create databases dbtext01;
    2,修改配置(settings.py)
    DATABASES = {
       'default': {
           'ENGINE': 'django.db.backends.mysql',
           'NAME': 'dbtext01',
           'HOST': '127.0.0.1',
           'PORT': 3306,
           'USER': 'root',
           'PASSWORD': "123456"}}
    3,配置pycharm数据库显示
    4,项目同名文件夹下的__init__配置
    import pymysql
    pymysql.install_as_MySQLdb()
       
    # orm语句特点

    1,惰性查询  res = models.Book.object.all()   # 不会去查
    print(res)                              # 用的时候才查
       
    2,查询优化
       # only
       res = models.Book.object.only(title)    # 获取所有对象,显示title字段,for循环时,查看title不走数据库
       # defer
       res = models.Book.object.defer(title)   # 与only刚好相反
       
       # 跨表查询相关
       select_related("联表")    # 联表join查询出来的数据,再次查询时,不会走数据库(只能放外键字段,一对一,一对多)
       prefetch_related("联表")  # 子查询in

    4.1 单表操作

    # 常用字段属性
    1,null
    如果为True,Django 将用NULL来在数据库中存储空值。 默认值是 False.
    blank
    如果为True,该字段允许不填。默认为False。要注意,这与 null 不同。null纯粹是数据库范畴的,而 blank 是数据验证范畴的。如果一个字段的blank=True,表单的验证将允许该字段是空值。如果字段的blank=False,该字段就是必填的。

    2,default
    字段的默认值。可以是一个值或者可调用对象。如果可调用 ,每有新对象被创建它都会被调用,如果你的字段没有设置可以为空,那么将来如果我们后添加一个字段,这个字段就要给一个default值

    3,primary_key
    如果为True,那么这个字段就是模型的主键。如果你没有指定任何一个字段的primary_key=True,Django 就会自动添加一个IntegerField字段做为主键,所以除非你想覆盖默认的主键行为,否则没必要设置任何一个字段的primary_key=True

    4,unique
    如果该值设置为 True, 这个数据字段的值在整张表中必须是唯一的

    5,choices
    由二元组组成的一个可迭代对象(例如,列表或元组),用来给字段提供选择项。 如果设置了choices ,默认的表单将是一个选择框而不是标准的文本框,<br>而且这个选择框的选项就是choices 中的选项。
    6,db_index
      如果db_index=True 则代表着为此字段设置数据库索引。

    # DatetimeField、DateField、TimeField这个三个时间字段,都可以设置如下属性。
    7,auto_now_add
       配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。

    8,auto_now
       配置上auto_now=True,每次更新数据记录的时候会更新该字段,标识这条记录最后一次的修改时间。

    ### choices属性
    sex = models.IntegerField(choices=((1, '男性'), (2, '女性')))

    数据库里面存的是1或者2
    通过model模型类对象.get_属性名称_display()可以获取到数字对应的文本内容


    # 创建字段
    class Book(models.Model):
       title = models.CharField(max_length=32)    # varchar(32)
       price = models.DecimalField(max_digits=5,decimal_places=2)   # decimal(5,2)
       pub_date = models.DateField()      # date
       publish = models.CharField(max_length=32)

    # 添加字段
           age = models.IntegerField()
           1,命令行添加默认值
           2,可以为空   null = True
           3,自己添加默认值  default = "18"
           
    # 修改字段
      直接修改,再执行迁移命令
           
    # 删除字段
      注释掉,再执行迁移命令(数据即消失)
       
    # 数据库迁移
    python manage.py makemigraitons (将操作记录记录到migrations文件下)
    python manage.py migrate         (将操作记录记录同步到数据库)

    4.1.1 单表增

    1,配置路由
    2,views写逻辑
    3,访问网页

    def home(request):

       ### 方法一
       obj = models.Book(
           title='西游记后传',
           price=2.8,
           # pub_date='2000-08-12', #这样的格式字符串
           pub_date=datetime.datetime.now(),  #时间日期类型
           publish='31期红浪漫出版社',
      )
       obj.save()
       
       ### 方法二
       models.Book.objects.create(
           title='西游记前传',
           price=3,
           pub_date=datetime.datetime.now(),
           publish='夕阳红出版社',
      )
       
       ### 批量增加
       bj_lst = []
       for i in range(10):
           obj = models.Book(
               title=f'西游记前传{i}',
               price=4,
               pub_date=datetime.datetime.now(),
               publish='夕阳红出版社',
          )
           obj_lst.append(obj)
       models.Book.objects.bulk_create(obj_lst)
       
       
       return HttpResponse("ok")

    4.1.2 单表改

    def home(request):
    ### 方法一
       models.Book.objects.filter(id = 2).update(price = "5.88")
       models.Book.objects.filter(id = 2).update(**kwargs)
    ### 方法二
       obj = models.Book.objects.get(id = 3)
       obj.price = 9.99
       obj.save()
       return HttpResponse("ok")

    4.1.3 单表删除

    def home(request):

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

       return HttpResponse("ok")

    4.1.4 单表查询

    # QuerySet 对象(类似于列表对象)
    models.Book.objects.filter()                         # 所有记录
    models.Book.objects.all()                            # 所有记录
    models.Book.objects.filter(id = 5)                   # 筛选记录
    ### 双下划线模糊匹配语法(字段__方法=“val”)
       startswith           # 开头
       endswith             # 结尾
       contains             # 包含
       in                   # 内
       range                # 区间
       year                 # 年
       mouth                # 月
       gt/gte               # 大于
       lt/ite               # 小于
       i                    # 不区分大小写
    models.Book.objects.exclude(id=5)                    # 排除记录
    models.Book.objects.order_by("id")                   # 记录排序
    models.Book.objects.order_by("id").reverse()         # 排序后反转
    models.Book.objects.filter(id=5).count()             # 筛选后计数
    models.Book.objects.filter(id=5).values()            # 筛选后查看值(每一条数据为字典)
    models.Book.objects.filter(id=5).values_list()       # 筛选后查看值(每一条数据为元组)
    models.Book.objects.all().values("price").distinct() # 记录去重

    # models.Book 实例对象
    models.Book.objects.get(id=5)                   # 只查一条(多少都报错)
    models.Book.objects.filter(id=5).first()        # 第一条
    models.Book.objects.all()[0]                    # 第一条
    models.Book.objects.filter(id=5).last()         # 最后一条

    # 记录
    models.Book.objects.filter(id=5).exists()       # 有无这条记录

    4.2 多表操作

    注意事项:ForeignKey(db_constraint = False)   取消强制约束效果(级联删除)


    # 创建表
    from django.db import models

    # 作者表
    class Author(models.Model): #比较常用的信息放到这个表里面
       name=models.CharField( max_length=32)
       age=models.IntegerField()  #int
       # 与AuthorDetail建立一对一的关系,一对一的这个关系字段写在两个表的任意一个表里面都可以
       ad = models.OneToOneField(to="AuthorDetail", to_field='id', on_delete=models.CASCADE)     # 自动加_id

    # 作者详细信息表
    class AuthorDetail(models.Model):#不常用的放到这个表里面
       birthday=models.DateField()
       telephone=models.CharField(max_length=11)
       addr=models.CharField(max_length=64)


    # 出版社表
    class Publish(models.Model):
       name=models.CharField( max_length=32)
       city=models.CharField( max_length=32)


    # 书籍表
    class Book(models.Model):
       title = models.CharField( max_length=32)
       publishDate=models.DateField()
       price=models.DecimalField(max_digits=5,decimal_places=2)
       publish=models.ForeignKey(to="Publish") # 自动加_id 默认级联删除,默认关联的是另外一张表的主键字段
       authors=models.ManyToManyField(to='Author',) # 多对多外键建议放到查询频率多的一方,自动创建第三张表,id author_id book_id,不会作为本表的字段出现

     

    4.2.1 多表增加

    # 一对多 (书与出版社)  外键字段在书籍表
    1,直接写实际字段
    models.Book.objects.create(
           title=data["title"],
           price=data["price"],
           publishDate=data["publishDate"],
           publish_id = 1,)
    2,先获取外键对象,再指定外键值(自动获取主键值)
    obj = models.Publish.objects.filter(pk=1).first()
    models.Book.objects.create(
           title=data["title"],
           price=data["price"],
           publishDate=data["publishDate"],
           publish_id = obj,)
       
    # 多对多 (作者与书) 操作第三张关系表
    1,拿到book对象
    book_obj = models.Book.objects.get(id=1) # 拿到书籍id为1的对象,给他添加做作者
    2,添加另一张表的id字段
    book_obj.authors.add(1,2) # 拿到了第三张表的字段authors,实际上拿到了第三张表,添加id为1,2的俩位作者,同样支持放对象

    4.2.2 多表更新

    # 一对一和一对多
    models.Author.objects.get(id=1).update(name = 'bajie')

    # 多对多修改
    ret = models.Book.objects.get(id=2)
    ret.authors.set([1,])         # 只有一个值,先删除再添加,如果有就不动,必须是可迭代对象

    4.2.3 多表删除

    # 一对一和一对多 ,基本和单表一样(级联删除)
    models.Author.objects.get(id=1).delete()
    models.AuthorDetail.objects.get(id=2).delete()
    models.Book.objects.get(id=1).delete()

    # 多对多删除
    ret = models.Book.objects.get(id=2)
    ret.authors.clear()                 # 清空该书籍对应的第三张表中的记录
    ret.authors.remove(3,4)             # 指定删除该书和哪些作者的关系

    4.2.4 多表查询

    # 查询方向 :
    正向:外键字段在Book,用Book查出版社为正向;否则为反向
       '''
      正向查询按字段
      反向查询按表名小写
      '''
           
    # 子查询(基于对象的跨表查询)
    # 正向
       book_obj = models.Book.objects.filter(pk=1).first()
       book_obj.publish.name     # 拿到了出版社对象(book与publish联表),用字段查
       """
      当结果可能有多个时,需要加 .all()
      如果为空,需要加all()
      """
       
       # 反向
       publish_obj = models.Publish.objects.filter(name = "山西出版社").first()
       res = publish_obj.book_set.all()
       """
      当查询结果有多个时需要加 _set.all()
      """
       
    # 联表查询(基于双下划线的跨表查询)
    """
    如果跨表,查到外键字段,那么直接跨到了外键字段关联的那张表;无限跨表
    """
    # 正向(先筛选再关联)
       res = models.Book.objects.filter(pk=1).values("publish__name","addr")  # 可多值查询
       print(res)
       
       # 反向(先关联再筛选)
    res = models.Publish.objects.filter("book__id" = 1).values("name","book__name")
       
       
    # 聚合查询(aggregate)
       from django.db.models import Max,Min,Sum,Count,Avg
       # 通常情况配合分组使用
       models.Book.objects.aggregate(Avg("price"))
       
    # 分组查询(annotate----group by)
    '''分组之后,除了分组字段,其他字段都无法看到'''
       
    '''
    严格模式:
    '''
       
    # models 后面是什么,就按什么分组 ,只要是queryset对象就可以无限.
    res = models.Book.objects.annotate()    # 按书分组
       
       # 方式一                         # 别名   个数 联表     继续过滤   获取值    
       res = models.Book.objects.annotate(n = Count("author")).filter().values(n)    # 按书分组
    # 方式二
       res = models.Book.objects.values("price").annotate()   # 按照字段分组,先values,如果报错考虑严格模式
       
    # F 查询
    from django.db.models import F
    # 同一张表俩列比较
       models.Book.objects.filter(点赞字段__gt=F("评论字段"))
       # 统一处理
       models.Book.objects.update(price=F('price') + 50)    # 价格统一加50元
       
    # Q 查询
    from django.db.models import Q
       # 处理filter参数有多个 and(,) , or(|) , not (~) 用Q包裹
       models.Book.objects.filter(~Q(price__gt=3)|Q(id = 1))
       # 高阶用法:
       q = Q()
       q.children.append("点赞字段__gt",100)
       q.children.append("评论字段__lt",60)
       models.Book.objects.filter(q)   # 默认是and关系
      修改关系:q.connector = "or"

    4.3 锁与事务

    # 原生SQL加锁 for update;
    begin;                        # 开启事务
    select * from t1 for update   # 加锁
    commit;                       # 解锁

    # ORM 加锁
    from django.db import transaction     # 引入事务

    @transaction.atomic       # (被装饰函数中的sql捆绑为事务)
    def insert(requset):
           with @transaction.atomic()    # (被装饰函数中的sql捆绑为事务,小范围)
          models.Book.objects.filter(id=1).select_for_update()   # 加锁

    4.4 ajax ( 异步提交,局部刷新 )

    使用jquery封装之后的版本(需要导入jquery)
    # 将提交按钮变为普通按钮取消刷新效果
       用户名:<input type="text" id="name"></input>
       密码:<input type="password" id="pwd"></input>
       <input type="button" id="btn">提交</input>
       
    # 给提交按钮绑定事件
    $("#btn").click(function(){
        # 获取数据
           var name = $("#name").val()
           var pwd = $("#pwd").val()
           $.ajax({
               url:"/longin/"                     # 不指定默认当前地址
               type:"post"                        # 请求方法
               data:{username:name,password:pwd}  # 提交数据
               dataType:true                      # 自动反序列化
               # 根据状态码判断请求报错与否
               success:function(res){  
                   if (res === "ok"){
                       location.href= "跳转页面url"
                  }
                   elif (res === "error"){
                       做一些提示
                  }
              }         # res 接受post请求返回的数据
               error:function(res){
                   做一些效果展示啥的逻辑
              }
          })
    })

    4.4.1 ajax发送json格式数据

    $(标签).click(function(){ 
       $.ajax({
           url:""
           type:"post"
           data:JSON.stringify({"name":"八戒"}), # 将数据转化为json格式
           contentType:"application/json"        # 指定发送json编码格式
           success:function(){},
           error:function(){},
      })
    })
    # 后端
    request.is_ajax()           # 获取是否是ajax请求
       # json格式数据
       data_bytes = request.body                 # 才能获取到
       data = json.loads(data_bytes)             # 反序列化

    4.4.2 文件上传

    from表单上传

    # form表单     
       1,mothed = "post"
       2,encype = "multipart/form-data"  # 文件分片发送
       
       
    # 视图层
    data = request.FILES.get("属性")        # 拿到文件句柄
    data.name                               # 文件名字
    with open(data.name , "wb") as f:
       for i in data.chunks:     # 读取数据不是按 ,默认65536B 64k,固定大小
           f.write(i)                          # 写入文件
           

    ajax 文件上传

    $(标签).click(function(){
       # 1,文件对象 f
       # 2,利用ForData处理对象
       var formdata = new FormData();
       formdata.append("key","普通数据");
       formdata.append("key",f)
       
       $.ajax({
           url:""
           type:"post"
           data:formdata,
           processData:false,     # 不需要任何处理
           contentType:false,     # 不需要任何编码,自动识别formdata对象
           success:function(args){},
           error:function(args){},
      })
    })

    # 后端

    data = request.FILES.get("key")        # 拿到文件句柄
    data.name                               # 文件名字
    with open(data.name , "wb") as f:
       for i in data.chunks:     # 读取数据不是按 ,默认65536B 64k,固定大小
           f.write(i)                          # 写入文件

    4.5 cookie与session

    服务端保存在客户端浏览器上的信息称之为    cookie
    数据保存在服务端上的信息称之为           session
    服务端不保存数据,加密处理后发送给客户端   token

    cookie操作

    # 保存用户登录状态
    obj = redirect("/home/")
    # 让浏览器记录cookie数据(设置)
    obj.set_cookie(k,v)
    # 设置多组
      obj.set_cookie(k,v,max_age = 3)  # 3秒过期
           # 加盐
          obj.set_signed_cookie(k,v,"盐")
           # 获取
          request.get_signed_cookie(k,salf)
       # 修改(相同键设置不同的值)
      obj.set_cookie(k,xx)  
       # 删除
      obj.delete_cookie(k)  
    # 返回值(登录之后才能看到的页面)
    return obj
    # 获取cookie
    request.COOKIES.get(k)

    # 注意点
    1,明文存储
    2,大小限制(一个浏览器最多保存20个cookie)

    session

    1,密文存储
    2,大小无限制
    3,数据在服务端数据库

    # 设置(可以设置多条)
    '''django表中数据,同一个计算机上同一个浏览器只有一条/节省资源'''
    request.session[k] = v
       1,操作session,django会自动生产一张表:django_session(key,values,过期时间(默认14天))
       2,生产一个随机字符串key,对应的值
       3,序列化加密,保存到django-session表中
       4,将随机字符串返回给客户端浏览器保存
    # 获取
    request.session[k]
    request.session.get(k)
       1,获取sessionid对应的字符串
       2,拿着字符串去数据库查找对应数据
       3,娶不到,返回None
    # 设置过期时间
    request.session.set_expiry()
    1,整数      
       2,时期对象    到期失效
       3,0          窗口关闭失效
       4,不写       即默认
    # 删除(注销)
    request.session.delete()     # 只删除服务端
    request.session.flush()      # 都删

    5, 中间件(MIDDLEWARE)

    # 自定义中间件
       1,app下创建文件夹mymidd,xx.py文件

       from django.utils.deprecation import MiddlewareMixin

       class Auth(MiddlewareMixin):
           def process_request(self,request):  # 执行中间件
               print("中间件请求执行了")
               # 如果返回三板斧,不继续,原路返回(不允许访问)
               
           def process_view(self,request,view_func,...):
               print(view_func)             # 要执行的视图函数对象;
               return HTTPResponse("嘿嘿嘿") # 如果返回了HTTPResponse,那么视图函数就不走了
               
           def process_exception(self,request,exception):
               # 要执行的视图函数对象请求错误时执行
               print(exception)    # 打印报错信息
               
           def process_template(self,request,response):
               # 没什么用
               
           def process_response(self,request,response):
               print("中间件响应执行了")
               return response            # 视图函数响应对象
          # 默认返回形参response
           
       2,配置setting文件 MIDDLEWARE(从上到下执行中间件)
           "app.mymidd文件夹.xx文件.方法"    # 每次请求来了自动执行

    5.1 csrf(跨站请求伪造)

    """
    钓鱼网站:
    假中国银行         用户       真中国银行
    """
    form 表单解决 # post请求
    {% csrf_token %}    

    ajax 解决
    """引入静态文件,"""
    $("#d1").click(function(){
           url:"",
           type:"post",
           # 第一种
           data:{数据key:数据value,"csrfmiddlewaretoken":"{{ csrf_token}}"}
           # 第二种 引入静态js文件
           data:{数据key:数据value}
           success:function(){}
      })

    # 装饰器
         from django.views.decorators.csrf import csrf_protect,csrf_exempt

       
       
    FBV
    # csrf_protect   需要校验
    # csrf_exempt   忽视校验

    CBV模式
    @mothed_decorator(csrf_protect,name = "方法")
    csrf_exempt    只能给dispath加

    django外部脚本调用django环境

    import os
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "database.settings")    # 去 manage.py 找

    import django
    django.setup()

    from app01 import models

    正文

     

     

     

  • 相关阅读:
    [BTS] BizTalk host BizTalkServerApplication throttled because DatabaseSize exceeded the configured throttling limit.
    Linux sed 批量替换字符串方法
    MYSQL中的POSITION方法
    wc (Word Count)
    sudo
    关于数据库timestamp类型问题
    SQL中存储过程和自定义函数的区别
    数据库存储过程
    五 : springMVC拦截器
    四 : springMVC各种跳页面传值
  • 原文地址:https://www.cnblogs.com/zhoulangshunxinyangfan/p/13716121.html
Copyright © 2011-2022 走看看