【Django】中间件/Auth模块

Django中间件 Django中间件类似于Django的保安。请求的时候需要先经过中间件才能到达Django后端(urls,views,templates,models),响应走的时候也需要经过中间件才能到达web服务网关接口。 Django默认的七个中间件 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] 我们点进去几个组件查看源码: class SecurityMiddleware(MiddlewareMixin): def __init__(self, get_response=None): pass def process_request(self, request): path = request.path.lstrip("/") if (self.redirect and not request.is_secure() and not any(pattern.search(path) for pattern in self.redirect_exempt)): host = self.redirect_host or request.get_host() return HttpResponsePermanentRedirect("https://%s%s" % (host, request.get_full_path())) def process_response(self, request, response): ... return response class CsrfViewMiddleware(MiddlewareMixin): def process_request(self, request): pass def process_view(self, request, callback, callback_args, callback_kwargs): ... return self._accept(request) def process_response(self, request, response): ... return response class AuthenticationMiddleware(MiddlewareMixin): def process_request(self, request): assert hasattr(request, 'session'), ( "The Django authentication middleware requires session middleware " "to be installed. Edit your MIDDLEWARE%s setting to insert " "'django.contrib.sessions.middleware.SessionMiddleware' before " "'django.contrib.auth.middleware.AuthenticationMiddleware'." ) % ("_CLASSES" if settings.MIDDLEWARE is None else "") request.user = SimpleLazyObject(lambda: get_user(request)) 不难发现一些规律: ...

2019年9月25日 · 3 分钟

【Django】form组件/cookie与session

**多对多三种创建方式 ** 1.全自动 优势:不需要你手动创建第三张表 不足:由于第三张表不是你手动创建的,也就意味着第三张表字段时固定的无法做扩展 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) authors = models.ManyToManyField(to='Author') class Author(models.Model): name = models.CharField(max_length=32) 2.纯手动 自己创建第三张表 优势:第三张表可以任意的扩展字段 不足:orm查询不方便 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) class Author(models.Model): name = models.CharField(max_length=32) class Book2Author(models.Model): book = models.ForeignKey(to='Book') author = models.ForeignKey(to='Author') create_time = models.DateField(auto_now_add=True) 3.半自动(推荐使用) 优势:结合了全自动和纯手动的两个优点 不足:不再支持多对多字段的add(),set(),remove(),clear()方法 class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_places=2) authors = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author')) # through 告诉django orm 书籍表和作者表的多对多关系是通过Book2Author来记录的 # through_fields 告诉django orm记录关系时用过Book2Author表中的book字段和author字段来记录的 class Author(models.Model): name = models.CharField(max_length=32) # books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=('author', 'book')) class Book2Author(models.Model): book = models.ForeignKey(to='Book') author = models.ForeignKey(to='Author') create_time = models.DateField(auto_now_add=True) forms组件 ...

2019年9月24日 · 3 分钟

【Django】Ajax/序列化组件/sweetalert/分页器

choices参数 我们存用户信息性别时,写入数据库时,写入的是数字1或2, 但从数据库读取时,我们又不能直接将数字展示给用户, 我们需要将1和2对应的男女展示给用户 choices的定义 choices参数是在models中定义 from django.db import models class User(models.Model): username = models.CharField(max_length=32) age = models.IntegerField() choices = ( (1,'男'),(2,'女'),(3,'其他') ) gender = models.IntegerField(choices=choices) choices怎么用 print(user_obj.get_gender_display()) # 只要是choices字段 在获取数字对应的值 # 固定语法:get_choices字段名_display() choices容错 比如数据库中某个用户的gender存的是4, 但是choices中没有4对应的值那么不会报错, 而是展示的是数据库中存的这个值4 user_obj = models.User.objects.filter(name='jason').first() print(user_obj.get_gender_display()) # 男user_obj = models.User.objects.filter(name='tank').first() print(user_obj.get_gender_display()) # 4 MTV和MVC模型 django框架 自称为是MTV框架 M:models T:templates V:views MVC M:models V:views C:controller控制器(urls) 本质:MTV其实也是MVC Ajax 特点: 异步提交 局部刷新(比如注册页面,实时检测用户名是否已存在) 目前发送请求的方式 GET POST a标签href属性 GET请求 ...

2019年9月23日 · 3 分钟

【Django】ORM中常用字段和参数

常用字段 常见字段 AutoField int自增列,必须填入参数primary_key=True。当model中如果没有自增列,则会自动创建一个列名为id的列。 IntegerField 一个整数类型,范围在-214748368to214748367。(一般不用它来存手机号,位数也不够,直接用字符串存) CharField 字符类型,必须提供max_length参数,max_length表示字符长度。 这里需要知道的是Django中的CharField对应的MySQL数据库中的varchar类型,没有设置对应char类型的字段,但是Django允许我们自定义新的字段,下面我们来自定义对应于数据库的char类型 EmailField() varchar(254)内部是个varchar字段** ** BooleanField(Field) is_delete = BooleanField() 给该字段传值的时候 你只需要传布尔值即可 但是对应到数据库 它存的是0和1 TextField(Field) - 文本类型 用来存大段文本 FileField(Field) - 字符串,路径保存在数据库,文件上传到指定目录 - 参数: upload_to = "" 用户上传的文件会自动放到等号后面指定的文件路径中 storage = None 存储组件,默django.core.files.storage.FileSystemStorage 自定义char字段 from django.db import models # Create your models here. #Django中没有对应的char类型字段,但是我们可以自己创建 class FixCharField(models.Field): ''' 自定义的char类型的字段类 ''' def __init__(self,max_length,*args,**kwargs): self.max_length=max_length super().__init__(max_length=max_length,*args,**kwargs) def db_type(self, connection): ''' 限定生成的数据库表字段类型char,长度为max_length指定的值 :param connection: :return: ''' return 'char(%s)'%self.max_length #应用上面自定义的char类型 class Class(models.Model): id=models.AutoField(primary_key=True) title=models.CharField(max_length=32) class_name=FixCharField(max_length=16) gender_choice=((1,'男'),(2,'女'),(3,'保密')) gender=models.SmallIntegerField(choices=gender_choice,default=3) DateField ...

2019年9月20日 · 3 分钟

【Django】模型层

ORM单表操作 单表操作演示表 class Book(models.Model): name = models.CharField(max_length=32) price = models.DecimalField(max_digits=8,decimal_place=2) publish = models.CharField(max_length=32) author = models.CharField(max_length=32) create_time = models.DateField(null=True) # 配置auto_now_add=True,创建数据记录的时候会把当前时间添加到数据库。 # 配置上auto_now=True,每次更新数据记录的时候会更新该字段。 新增数据 # 第一种:有返回值,并且就是当前被创建的数据对象 modles.Book.objects.create(name='',price='',publish='',author='',create_time='2019-5-1') # 第二种:先实例化产生对象,然后调用save方法保存 book_obj = models.Book(name='',price='',publish='',author='',create_time='2019-5-1') book_obj.save() # 2.验证时间格式字段即可以传字符串也可以传时间对象 import datetime ctime = datetime.datetime.now() book = models.Book.objects.create(name='',price='',author='',create_time=ctime) 删除数据 """删除数据""" # 1.删除书名为xxx的这本书 queryset方法 res = models.Book.objects.filter(name='').delete() print(res) # 2.删除书名为xxx的这本书 queryset方法 res = models.Book.objects.filter(name='').first() res.delete() 修改数据 # 1.queryset修改 models.Book.objects.filter(name='').update(price='') # 2.对象修改 book = models.Book.objects.filter(name='').first() book.price = 66.66 book.save() # 对象只有保存方法 这样也能实现修改需求 查询数据的13个方法 ...

2019年9月19日 · 3 分钟

【Django】模板层

模版语法 两大类 {{}} 变量相关 {%%} 逻辑相关 给模版传值 python所有的数据类型都可以被传递到前端页面 注意在传递函数的时候,会自动加括号调用,前端展示的是函数调用的之后的返回值(ps:前端在调用函数的时候,是不支持给函数传递额外参数的) 如果你想在前端获取后端传递的某个容器类型中的具体元素 那么你可以通过句点符来获取具体的元素 .索引 .键 变量 在Django的模板语言中按此语法使用:{{ 变量名 }}。 当模版引擎遇到一个变量,它将计算这个变量,然后用结果替换掉它本身。 变量的命名包括任何字母数字以及下划线 ("_")的组合。 变量名称中不能有空格或标点符号。 点(.)在模板语言中有特殊的含义。当模版系统遇到点("."),它将以这样的顺序查询: 字典查询(Dictionary lookup) 属性或方法查询(Attribute or method lookup) 数字索引查询(Numeric index lookup) 注意事项: 如果计算结果的值是可调用的,它将被无参数的调用。 调用的结果将成为模版的值。 如果使用的变量不存在, 模版系统将插入 string_if_invalid 选项的值, 它被默认设置为’’ (空字符串) 。 几个例子: view中代码: def template_test(request): l = [11, 22, 33] d = {"name": "alex"} class Person(object): def __init__(self, name, age): self.name = name self.age = age def dream(self): return "{} is dream...".format(self.name) Alex = Person(name="Alex", age=34) Egon = Person(name="Egon", age=9000) Eva_J = Person(name="Eva_J", age=18) person_list = [Alex, Egon, Eva_J] return render(request, "template_test.html", {"l": l, "d": d, "person_list": person_list}) 模板中支持的写法: ...

2019年9月18日 · 5 分钟

【Django】路由层、视图层

1.Django orm中表与表之间建关系 数据库表与表之间建关系 图书管理系统为例,书籍表,作者表,出版社表,作者详情表 书籍和出版社是一对多 外键字段建在书籍表中 书籍和作者是多对多 需要第三个表记录多对多关系 作者和作者详情是一对一 记录在最常用的那张表 Django orm中 一对多 ForeignKey(to=‘Publish’) 一对一 OneToOneField(to=‘AuthorDetail’) 多对多 ManyToManyField(to=‘Author’) 注意:前面两个关键字会自动在字段后面加id 最后一个关键字 并不会产生实际字段 只是告诉django orm自动创建第三张表 2.路由层 2.1 URL配置 基本格式【1.0版本】 from django.conf.urls import url urlpatterns = [ url(正则表达式, views视图函数,参数,别名), ] 基本格式【2.0版本】 from django.urls import path urlpatterns = [ path('articles/2003/', views.special_case_2003), path('articles/<int:year>/', views.year_archive), path('articles/<int:year>/<int:month>/', views.month_archive), path('articles/<int:year>/<int:month>/<slug:slug>/', views.article_detail), ] 2.0版本已经不能使用正则表达式,只能精准匹配 1.0版本参数说明 正则表达式:一个正则表达式字符串 views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串 参数:可选的要传递给视图函数的默认参数(字典形式) 别名:一个可选的name参数 Django版本区别 django1.X跟django2.X版本区别 1.路由层1.X用的是url,而2.X用的是path 2.路由层2.X中的path第一个参数不再是正则表达式,而是写什么就匹配什么 是精准匹配, 3.当你使用2.X不习惯的时候,2.X还有一个叫re_path,2.x中的re_path就是你1.X的url 4.虽然2.X中path不支持正则表达式 但是它提供了五种默认的转换器 ...

2019年9月17日 · 4 分钟

【Django】总览

Django简易版 1. 纯手撸一个简易版的web框架 1.1 手动处理socket请求 1.2 手动处理http请求 1.3 根据用户访问url的不同,响应不同的结果 2. wsgireg模块(web服务端网关接口) 2.1 封装socket代码 2.2 拆分请求发来时的http格式的数据为一个大字典 2.3 打包数据为响应发回时的http格式的数据 2.4 启动 server = make_server('127.0.0.1',8080,run) # 实时监测,一旦有客户端接入,自动加括号调用run方法 server.server_forever() # 启动服务端 3. 如何给html页面传递数据 3.1 字符串替换 3.2 jinja2模块 1. 模版的渲染(传数据) 2. 模版语法(极其贴近python语法) from jinja2 import Template # 将文本格式的html数据传入Template render() # 模板语法 {{ data }} {% for user in user_list %} {% endfor %} # 模板语法 只有两种情况 {{}}:变量相关 {%%}:逻辑相关 4.对不同的功能拆封成不同的文件 templates文件夹(专门放html文件) urls.py views.py Django总览版 ...

2019年9月16日 · 3 分钟

【Django】框架简介

Web框架本质 我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端。 这样我们就可以自己实现Web框架了。 半成品自定义web框架 import socket sk = socket.socket() sk.bind(("127.0.0.1", 80)) sk.listen() while True: conn, addr = sk.accept() data = conn.recv(8096) conn.send(b"OK") conn.close() 可以说Web服务本质上都是在这十几行代码基础上扩展出来的。这段代码就是它们的祖宗。 用户的浏览器一输入网址,会给服务端发送数据,那浏览器会发送什么数据?怎么发?这个谁来定? 你这个网站是这个规定,他那个网站按照他那个规定,这互联网还能玩么? 所以,必须有一个统一的规则,让大家发送消息、接收消息的时候有个格式依据,不能随便写。 这个规则就是HTTP协议,以后浏览器发送请求信息也好,服务器回复响应信息也罢,都要按照这个规则来。 HTTP协议主要规定了客户端和服务器之间的通信格式,那HTTP协议是怎么规定消息格式的呢? 让我们首先打印下我们在服务端接收到的消息是什么。 import socket sk = socket.socket() sk.bind(("127.0.0.1", 80)) sk.listen() while True: conn, addr = sk.accept() data = conn.recv(8096) print(data) # 将浏览器发来的消息打印出来 conn.send(b"OK") conn.close() 输出: b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nDNT: 1\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\nCookie: csrftoken=RKBXh1d3M97iz03Rpbojx1bR6mhHudhyX5PszUxxG3bOEwh1lxFpGOgWN93ZH3zv\r\n\r\n' 然后我们再看一下我们访问博客园官网时浏览器收到的响应信息是什么。 ...

2019年9月12日 · 6 分钟