一、 设计模式
1、 MVC设计模式:
2、MTV设计模式:
关键是路由机制,视图,模板和模型
(3)两者关系:
MTV本质上与MVC没有什么区别
二、URL路由机制:
1、URL通过定义、传参、命名以及转换等匹配到views中的函数
2、路由配置:
-
全局路由文件在settings.py中的ROOT_URLCONF变量指定,默认是:project_name.urls
-
在指定的路由文件中,通过urlpatterns=[path(‘route’,fun),re_path(‘route’,fun),…]定义
(1)定义:
- path( ) 与re_path()的区别是后者的route为正则表达式;path是2.0版本后新提出的
- route有三种表示方式:
- 精确字符串:静态响应,注意开头没有/ 而结尾一定有/
- 转换格式类型:<类型:变量名>,可以为funct传参数,str int slug uuid path
- 正则表达式类型:命名格式(?ppattern) ;普通格式(pattern)
- fun有两种表示方式:
- 处理函数名字,注意引用包
- include(“app_name.urls”) ,注意在app_name应用中定义urls.py文件并定义本地路由
根目录(即与manage.py同级)path中为"" re_path中为(’^$’)
(2) 传递参数:有位置参数和关键字参数两种,后者注意函数定义的形参保持一致
- route中<>格式定义,直接可以在函数定义中使用
- route中正则表达式匹配的组(即用()括起来的)是位置参数
- 在path(re_path)中增加一个字典类型的参数,{key:value,key1:value1} ,在函数中定义中使用;但是由于这种“写死”了参数,其实传参也没有什么意义- **自定义路由converter**:本质是一个类,可能有很多转换器,即转换格式 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210413222529148.PNG#pic_center) ①regex定义了正则表达式;to_python()将其转换为Python类型;to_url()针对的是提交的URL ②调用时在路由文件中,具体格式如下: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210413222906957.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQxMTQ3Nzg1,size_16,color_FFFFFF,t_70#pic_center)
(3)对多个URL去重:比如第一个为credit/reports/
3、路由流程
- 查询全局路由文件中的urlpatterns变量
- 按照先后顺序,对URL逐一匹配
- 找到第一个匹配停止查找执行相应的处理函数;如没找到,进行错误处理
三、模型
1、ORM:
Django采用ORM框架,可以将类与数据表对应起来,只需要通过操作类和对象就可以对数据表进行操作;另外还可以根据类生成数据库中的表;
2、数据库配置(项目的settings.py文件中):需要pip install pymysql
项目的settings.py文件中:
DATABASES= { 'default' : {'ENGINE':'django.db.backends.mysql', 'NAME':‘数据库名称’ , 'USER': '', 'PASSWORD':'', 'HOST': '' ,PORT:3306,} }
项目的__init__.py文件中:
import pymysql
pymysql.install_as_MySQLdb()
提前打开mysql的服务,这样就可以连接啦!
3、定义模型类(在相应应用的models.py文件中)
from django.db import models
class 类名(models.Model):
字段名=models.类型(参数列表)
#其中主键会自动生成,为id,不需要处理
class Meta:
db_table=’表名‘ #默认是 应用名_类名
(1)字段名不可以为Python保留字,也不可以使用多个下划线
(2)类型常见的有:CharField,TextField(多于4000字), IntergeField,DecimalField,FloatField,DateField,DateTimeField,FileField,ImageField等
(3)参数常见的有:max_length,primary_key(布尔类型),null(布尔类型),unique(布尔类型),default,db_index(布尔),db_column,blank(布尔)
其中null是针对数据库的,blank是针对后台管理的
(4)模型类的关系
①一对多:多类的定义中写: 关联属性名=models.ForeignField(‘一类名’)
②多对多:在其中的一个类中写:关联属性名=models.ManyToManyField(‘另一个类名’)
③一对一:在其中的一个类中写:关联属性名=models.OneToOneField(‘另一个类名’)
4、模型类的使用:
(1)模型类生成表:
python manage.py makemigrations #生成迁移文件
python manage.py migrate #执行迁移文件生成表
注:如果是已经存在的表,则模型类不需要迁移就可以与他对应
(2)模型类操作表
①查询
- 基本查询和条件查询:模型类名.objects.查询方法() ->QuerySet ,查询方法主要包含下面的几种:
all():返回对应的所有记录对象
filter(查询条件):返回符合条件的记录对象
exclude(查询条件):返回不符合条件的记录对象
get(查询条件):返回一个对象
注:查询条件的一般格式为: 字段–条件=值 ,条件为:exact,contains,endswith,startswith,isnull, in, gt(gte),lt(lte)
高级格式:django.db.models.Q :Q(条件1) 可以与 逻辑预算与或非结合;
django.db.models.F: F(’属性名’) 可以实现属性直接的比较 - 排序查询
QuerySet.order_by(’字段名‘) #默认为升序,’**-**字段名’为降序 - 聚合函数(from django.db.models import Sum,Count,Avg,Max,Min)
语法格式:QuerySet.aggregate(聚合类名(‘字段名’)), 返回字典{‘字段名_聚合类名’ :值} - 关联查询
一查多:obj.多类名(小写)_set.all() 返回与obj关联的所有多类对象;多类名.objects.查询函数(关联字段名–一类字段–条件名=值)
多查一:obj.关联属性.一类字段名;一类名.objects.查询函数(多类名–字段名–条件=值)
②插入、更新
对象.字段=值; 对象.save()
③删除
对象.delete()
5、查询集(QuerySet)
(1)惰性查询:只有在真正使用查询集中的数据时才会对数据库真正的查询
(2)缓存:当使用同一个查询集时,第一次实际查询,后面的使用是结果缓存
(3)查询集可以切片(但是不可以为负数),也可以遍历,实现了–getitem–()
(4)查询集判断空否 q.exists() 返回布尔类型
6、模型类的管理类:(相应的应用中的admin.py文件中)
(1)用法:
本地化,项目的settings.py文件中的 LANGUAGE_CODE和TIME_ZONE
创建管理员 python manage.py createsuperuser
admin.register(模型类名【,模型管理类】);这样当访问/admin的时候就可以在网页上看到数据库中的内容
(2)模型管理类是需要用户自己定义,可以定制的在页面显示的形式
7、模型类的管理器(上文提到的objects,也可以自己定制,models.Manage类)
(1)自定义管理器(在应用的models.py文件):继承models.Manage
在相应的模型类定义中增加一句: objects(可以随便取)=自定义管理器名();调用时: 模型类.objects.方法名()
(2)应用场景:改变查询集的结果集;可以在管理器中定义all filter exclude等方法
添加额外的方法,帮助操作对应的表;self.model可以获得对应的模型类
四、视图响应:
1、视图函数接受Http请求并返回响应,位于应用中的views.py文件中;其中路由配置(第二部分)是关键
2、视图响应类型:
- HttpResponse以及10个子类:
(1)HttpResponse+ Redirec PermanentRedirec NotModified BadReuqest Forbidden NotAllowed Gone ServerError NotFound
(2)HttpResponse(content,content_type,status=200,charset=None) #content为返回字符串,content_type为MIME类型
或 response=HttpResponse() response.write("") #当做类,可以多次写入响应的内容
- JsonResponse(data):data为字典类型,返回json类型数据
- StreamingHttpResponse(streaming_content) :streaming_content为迭代器形式的,一般可借助 调用用yield定义的函数
- FileResponse(stream):适合大文本,大二进制文件,为上一种类型的特殊形式
前两种为一次性响应;后两种为流式响应
3、注意路由不能判断请求类型,需要在视图函数前进行判断:
from django.view.decorators.http import require_http_methods
@requrie_http_methods([‘GET’,‘POST’,…])
def my_view(request):
4、视图函数:参数必须包含request,是一个HttpRequest对象,
常用的属性有:POST,GET,path,method,FILES,COOKIES,session
其中POST,GET,FILES,COOKIES可以看做字典类型,可以使用[key] 或者get(key)获取
5、错误视图:项目的settings的DEBUG=True或False决定看见否;当为False时,必须设置ALLOWED_HOSTS=[],一般可以为’*’
另外可以在templates下创建HTML错误页面,Django会自己调用,命名为对应的错误代码.html
6、cookie和session的用法
五、模板
1、模板:产生HTML文件(静态(css,js,html)+动态(模板语言))
2、模板的使用:
根目录下创建templates文件夹
项目的settings.py文件中TENPLATES中的DIRS设置模板路径[os.path.join(BASE_DIR,‘templates’,]
一般在templates下为每一个app单独创建文件夹,然后在内部创建html文件
注意:HTML文件引用时的URL从templates/的下一个开始
3、模板加载顺序:
首先是配置的路径;然后去INSTALLED_APPS下的每个应用去找模板(前提要有templates这个文件夹)
4、模板语言
(1)模板变量 {{变量名}} 或者{{变量名1.变量名2}} ,后者可以表示为dict[key]、obj.attr、 obj.func、 list[n]
(2)模板标签 {% %} :for- endfor if - else if -else -endif
(3)注释 {% commend%} {% endcomment %} ;{# #}
(4)过滤器:多模板变量进行操作,本质为函数, 语法: 模板变量 | 过滤器 【:参数】;
自定义过滤器:在相应的应用中创建templatetages文件夹,新建py文件,然后定义过滤器
from django.template import Library
library=Library()
@library.filter
def func(参数): #参数第一位过滤器前面的变量,第二个参数可以有也可以没有
然后在模板中 {% load 文件名%} 模板变量 | 过滤器 【:参数】
5、模板继承:
{% extends ‘URL’%} #'URL’为父模板的URL
子模板不同于父模板处需要提前通过{% block 名称%}—{% endblock 名称%}来预留,其中{{block.super}}表示父相应的内容
六、其他技术
1、静态文件(css,js,image)
(1)在根目录下新建static文件夹,并在里面继续分别创建css js image三个文件夹
配置:项目的settings.py文件中 static_url=’’(逻辑地址开头) staticfiles_dirs=[os.path.join(BASE_DIR,‘static’),]
(2)加载顺序:首先是配置目录;然后去app的static_url表示的值的文件夹下对应的文件夹下寻找
(3)static_url可以在模板中动态获得
{% load staticfiles %} {% static ‘url’ %}
注:静态文件的引用时的URL以static_url开头才可以
2、中间件:是django预留的函数接口,可以干预请求和相应过程,在每个视图函数调用前自动执行
(1)自定义中间件:创建py文件,定义中间类,然后在类内部重写中间函数(–init–,process_request,process_view,process_response,process_exception)
在项目的settings中将中间类进行注册
(2)匹配时按照注册的顺序从下往上开始匹配
(3)流程:
–init–,process_request,process_view,process_response,process_exception
另外:csrf中间件,用来防止跨站伪造攻击,只针对post提交,一般需要在相应的html页面中表单中{ % csrf_token %}解决403问题