以下内容只是在阅读django官方文档时简单理解后的记录,具体可以看文档
模型和数据库
django强大的功能就是ORM,一个model映射一张数据库表。
模型
1.模型创建
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
相当于数据库中的:
CREATE TABLE myapp_person (
"id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
"first_name" varchar(30) NOT NULL,
"last_name" varchar(30) NOT NULL
);
2.使用模型需要将APP名字加入到INSTALLED_APPS,添加新应用后务必运行manage.py migrate
字段
定义字段时务必要小心不要与模型API冲突。
1.字段类型
- 用于指定数据库数据类型(INTEGER,VARCHAR,TEXT)
- 渲染表单时默认使用的HTML视图(如 ,)
2.字段选项
- null 如果为True当该字段为空时,django会将数据库中该字段设置为NULL
- blank 是否允许为空 默认为False(设计表单验证)
- choices 默认表单部件是一个选择框,限制给出的选项
如:
from django.db import models
class Person(models.Model):
SHIRT_SIZES = (
('S', 'Small'),
('M', 'Medium'),
('L', 'Large'),
)
name = models.CharField(max_length=60)
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
也可以直接MedalType = models.TextChoices('MedalType', 'GOLD SILVER BRONZE')
- default 默认值
- help_text 额外的‘帮助’文本。随表单控件一同显示
- primary_key 主键(不设置默认自增id为主键)
id = models.BigAutoField(primary_key=True)
关联关系
1.多对一关联(ManyToOne)
使用class ForeignKey(to, on_delete, **options)
to:模型名字
on_delete:删除的参数,如下所示
- CASCADE 级联删除
- PROTECT 防止删除
- RESTRICT 与PROTECT不同的是,如果被引用的对象也引用了一个在同一操作中被删除的不同对象,但通过CASCADE关系,则允许删除被引用的对象。
ForeignKey.related_name
user = models.ForeignKey(
User,
on_delete=models.CASCADE,
related_name='+',
)
是模型为正向关系
2.多对多关系(ManyToMany)
如果我是你的朋友,那么你就是我的朋友
ManyToManyField.through_fields
决定使用中介模型的哪些字段来建立多对多关系如下:
class Person(models.Model):
name = models.CharField(max_length=50)
class Group(models.Model):
name = models.CharField(max_length=128)
members = models.ManyToManyField(
Person,
through='Membership',
through_fields=('group', 'person'),
)
3.OneToOne
如果没有为 OneToOneField 指定 related_name 参数,Django 将使用当前模型的小写名作为默认值。
装饰器
在不改变函数代码和调用方式的情况下,给函数添加新的功能,广泛用于权限校验和缓存等场景。
django还允许开发人员自定义装饰器来实现特定功能,可以是函数或类,并接受函数或方法作为参数,常定义在views.py文件中,调用时使用@符号。
中间件
用于请求和相应之间进行处理,以实现一些通用的功能。常用于修改请求和响应、执行额外的逻辑或检查请求或响应是否符合特定的规则,可以在django请求处理流程中的任何阶段被调用。
django自带了许多中间件,在settings.py文件中启用或禁用,可以自己编写。
URL调度器
- str匹配除了‘/’之外的非空字符串。
- int 匹配0或任意正整数
- slug 匹配数字字母横线组成的标签
- 匹配非空字段,包括路径分隔符
使用正则表达式
re_path(?Ppattern),name是组名,pattern是要匹配的模式。
包含其他的URLconfs
from django.urls import include, path
from apps.main import views as main_views
from credit import views as credit_views
extra_patterns = [
path('reports/', credit_views.report),
path('reports/<int:id>/', credit_views.report),
path('charge/', credit_views.charge),
]
urlpatterns = [
path('', main_views.homepage),
path('help/', include('apps.help.urls')),
path('credit/', include(extra_patterns)),
]
参数的捕获
被包含的URLconf会受到来自父URLconf捕获的任何参数
数据库事务
事务有原子性的一系列数据库操作,即使你的程序崩溃,数据库也会确保这些操作要么全部完成,要么全部都未执行。
1.django默认的事务行为
django默认的事务行为是自动提交。除非是正在执行,每个查询将会马上自动提交到数据库。使用事务还原原点,以确保需多次查询的ORM操作的一致性。
2.事务与HTTP请求
在web里,处理事务比较常用的方式是将每个请求封装在一个事务中。在django中,事先生成一个事务,如果相应能正常生成,django会提交该事务。而如果视图出现异常,django则会回滚该事务。为每个视图打开一个事务会带来一些开销,对性能的影响程度取决于应用执行的查询语句和数据库处理锁的能力。只有视图被限制在事务中执行,中间件在事务之外运行,渲染模板相应也是在事务之外运行的。
3.显式控制事务
django提供了一个API控制数据库事务
atomic(using=None, savepoint=True, durable=False)
atomic允许创建代码块来保证数据库的原子性。可以嵌套
4.停止事务管理
通过设置AUTOCOMMIT为False对数据库事务管理禁用
文件上传
django处理文件上传时,文件参数最终会被放置在request.FILES
简单文件上传的表单:
from django import forms
class UploadFileForm(forms.Form):
title = forms.CharField(max_length=50)
file = forms.FileField()
请求方式是POST,至少有一个文件字段被实际发布,并且发布请求的有enctype='multipart/form-data’属性时才hi包含数据,否则request.FILES为空
通常可以这样处理上传文件:
def handle_uploaded_file(f):
with open('some/file/name.txt', 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
使用chunks()而不是read()为了确保即使是大文件也不会将系统内存占满。
上传Handlers
当用户上传文件时,Django把文件传递给upload handler 是一个处理上传文件的很小的类。
默认小文件读入内存,小文件存在磁盘上。可以自己编写handler来定义django如何处理文件,可以限制用户层面的配额,动态压缩数据,渲染进度跳,可以将数据发送到其他存储地址,而不是本地。django将数据流式传输到磁盘上。
便捷函数
- get_object_or_404()
from django.shortcuts import get_object_or_404
def my_view(request):
obj = get_object_or_404(MyModel, pk=1)
相当于
from django.shortcuts import get_object_or_404
def my_view(request):
obj = get_object_or_404(MyModel, pk=1)
数据库测试
未测试创建单独的空白的数据库,不会产生’实际‘数据库,测试结束后数据库将被摧毁。
用户认证
django自带一个用户验证系统,负责处理用户账户、组、权限和基于cookies的用户会话。
认证系统包含以下部分:
- 用户
- 权限
- 组
- 可配置的密码哈希化系统
- 为登录用户或限制内容提供表单和视图工具
- 可插拔的后端系统
权限缓存
在第一次需要获取用户对象的权限检查时,ModelBackend才会缓存他们的权限。
django缓存
中高流量站点需要尽可能多的地削减开销,缓存的用处在此。缓存就是保存某些昂贵的计算结果资源,以便下次不必执行计算。
Django自带强大的缓存系统,可以保存动态页面,不必每次请求计算。
1.设置缓存
需要告诉系统要将缓存数据放在那里(数据库、文件系统、内存中)这会影响缓存的性能。
2.内存缓存
Memcached是一个完全基于内存缓存的服务器。以一个守护进程的形式运行,被分配了指定数量的RAM。
Memchached有一个很好的特性,可以在多台服务器上共享一个缓存。
3.Redis缓存
是一个可用于缓存的内存数据库,需要运行Redis服务器。
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.redis.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379',
}
}
4.虚拟缓存(用于开发模式)
5.本地内存缓存
日志
1.Logger
进入日志记录系统的入口点。每个记录器都是一个命名的可以将消息写入其中进行处理的存储桶。每条日志记录也包含日志级别,代表对应消息的严重程度。
2.Handlers
处理器是决定将什么消息发送给logger,描述了特殊的Logger行为,比如将消息、文件、网络socket发送到屏幕
3.Filter
使用表单
前端输入,后端处理接收到的数据。
HTML允许输入文本、选择选项、操作对象等发送到服务端。
处理表单只会用到GET和POST两种HTTP方法。post传输数据,为了传输会进行编码,然后发送到服务端并接受它的响应。POST用于可以更改系统的请求,GET不更改系统。
Django的Form类
核心组件是Form类,描述一张表单并决定她如何工作及呈现。
File对象
在内部,django在任何需要表示文件的时候都使用 django.core.files.File
>>> from django.core.files import File
# Create a Python file object using open() and the with statement
>>> with open('/path/to/hello.world', 'w') as f:
... myfile = File(f)
... myfile.write('Hello World')
...
>>> myfile.closed
True
>>> f.closed
分页
所有分页方法都使用Paginator类,完成了将QuerySet拆分为Page对象的所有繁重工作。
from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2)
>>> p.count
4
>>> p.num_pages
2
ListView 分页
django.views.generic.list.ListView 提供了一种内置的方式来对显示的列表进行分页。可以通过在你的视图类中添加:paginate_by 属性来实现此目的
from django.views.generic import ListView
from myapp.models import Contact
class ContactListView(ListView):
paginate_by = 2
model = Contact
在视图函数中使用 Paginator
from django.core.paginator import Paginator
from django.shortcuts import render
from myapp.models import Contact
def listing(request):
contact_list = Contact.objects.all()
paginator = Paginator(contact_list, 25) # Show 25 contacts per page.
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'list.html', {'page_obj': page_obj})
性能和优化
为什么要优化?
提升速度、减少耗存、网络要求等。优化时需要考虑多方面的问题,不要只是提高了程序运行时间但是内存耗尽,这样做的弊大于利。
django工具
django-debug-toolbar是一个可以深入了解代码,知道代码执行花费了多少件,可以显示页面生成的所有SQL查询,以及每个查询所用的时间。
第三方服务
有许多免费服务从远程HTTP客户端角度分析报告网页性能。
Yahoo’s Yslow
Google PageSpeed
级别排序
执行速度:数据库<python 语言<模板语言
数据库优化
索引:这是第一优先级,可以为经常查询的字段添加索引,但是维护索引的开销可能会超过查询速度的任何收益
合理使用字段类型