default:默认数据库
ENGINE:数据库引擎
NAME:数据库名称
USER:数据库登陆用户名
PASSWORD:数据库登陆密码
HOST:数据库访问地址
PORT:端口号
Django使用mysql数据库时需安装依赖:pip install mysqlclient
Django ORM模型中提供的常用字段:
对于CharField,max_length为必选参数
对于DateTimeField:
auto_now:更新时间为记录更改的时间
auto_now_add:记录创建的时间
每个类型都有可选参数,部分类型有必传参数。
一般情况下,第一个参数不指定名称。
1.(大多数模型类型的第一个参数)verbose_name:表示字段的含义
2.null,blank:是否为Null,空值(空字符串)
3.db.column:数据库表中对应的字段名称
4.default:不填写字段值时的默认值
5.primary_key,unique:主键,唯一索引
6.help_text:帮助文字
7.choices:可供选择的选项(get_xxx_display():展示choices对应的值)
1.检查模型是否编写无误
python manage.py check
2.生成同步原语
python manage.py makemigrations
3.执行同步
python manage.py migrate
元数据:在模型里再写一个类(Meta)
作用:对模型的补充说明
db_table:模型映射的数据库表的名称
ordering:指定数据表的默认排序规则
verbose_name:供编程查看的字段名称
abstract:True,抽象类,不会生成数据库表
proxy:代理模型(代理父模型的功能,并对父模型功能进行扩充)
参数:
to:关联的模型(必传)
on_delete:删除选项(必传)
related_name:是否需要反向引用,反向引用的名称
related_query_name:反向引用的名称
Django自带模型(类容模型):ContentType
它会将创建的模块和定义的模型都记录下来
通过外键ForeignKey(ContentType)关联复合模型。
GenericForeignKey关联模型
GenericRelation反向关联
Django shell:
1.从终端进入项目目录下,python manage.py shell
2.从pycharm进入[Python Console]
首先需要引入写好的模型
1.save():保存数据
2.create():新增数据
3.bulk_create():批量新增数据
user_obj = User(username=‘admin’,password=‘123’)
user_obj.save()
user_obj = User.objects.create(username=‘admin’,password=‘123’)
user1 = User(username=‘admin’,password=‘123’)
user2 =User(username=‘normal’,password=‘123’)
user3 = …user_list = [user1,user2,user3,…]
User.objects.bulk_create(user_list)
user1 = User(username=‘admin’,password=‘123’)
LoginHistory.objects.create(user=user1, *args, **kwargs)
注:需要传入外键关联的对象或是对象id
user_obj = User.objects.get(pk=1)
obj = LoginHistory.objects.earliest(‘created_at’)
注意异常的处理:
object,created = User.objects.get_or_create()
返回一个元组:(对象,是否创建)
在视图函数中使用。
user_obj = User.objects.last()
如果记录没有会返回None
user_list = User.objects.all()
user_obj = User.objects.get(pk=1)
user_obj.nickname = ‘admin’
user_obj.save()
方法一:统一修改
user_list = User.objects.all()
user_list.update(status=0)
方法二:循环逐一修改
for user in user_list:
user.status = 0
user.save()
bulk_update(objs,fields,batch_size=None)
objs:需要修改的记录列表
fields:指定需要修改的字段
batch_size:每次提交多少条记录进行修改
删除单条记录:
user_obj = User.objects.get(pk=1)
user_obj.delete()
删除多条记录:
User.objects.all().delete()
注意外键关联的删除
exists()判断结果集是否存在
User.objecrs.all.exists()
返回布尔值
print(QuerySet.query)
User.objects.filter(username__iexact=‘xxx’)
User.objects.filter(nickname__isnull=True).count()
User.objects.filter(username__icontains=‘xxx’)
User.objects.filter(username__in=[‘xxx’,‘xx’])
User.objects.filter(username__startswith=‘xxx’)
User.objects.filter(updated_at__date=日期对象)
外键关联查询:
UserProfile.objects.filter(user__nickname=‘管理员’)
user:UserProfile与User模型的外键关联
filter深入使用:
User.objects.filter(nickname__icontains=‘管理员’).filter(status=1)
User.objects.filter(nickname__icontains=‘管理员’, status=1)
&运算符:
user_list =User.objects.filter(nickname__icontains=‘管理员’)&User.objects.filter(status=1)
重点 Q()函数:
需要先引入
from django.db.models import Q
query1 = Q(nickname__icontains=‘管理员’, status=1)
User.objects.filter(query1)
AND:
query2 = Q(nickname__icontains=‘管理员’) & Q(status=1)
User.objects.filter(query2)
OR:
query3 = Q(username=‘xxx’) | Q(nickname__icontains=‘管理员’)
User.objects.filter(query3 )
1.安装
pip install django-debug-toolbar
2.使用-参考官方文档:
https://django-debug-toolbar.readthedocs.io/en/latest/installation.html
一:使用管理器的raw(sql)函数
返回django.db.models.query.RawQuerySet实例
二:获取数据库连接,游标,直接执行sql
使用分页也是查询优化的一部分
方式一:对查询结果集QuerySet进行分片
返回前n个对象:
User.objects.all()[:n]
返回第11到第20个对象
User.objects.all()[10:20]
[10:20]:切片左闭右开
page = request.GET.get('page', 1)
page = int(page)
page_size = 10
start = (page-1) * page_size
end = page * page_size
user_list = User.objects.all()[start:end]
方式二:使用django.core.paginator进行分页处理√
page = request.GET.get('page', 1)
page = int(page)
user_list = User.objects.all()
p = Paginator(user_list, 15)
page_data = p.get_page(page)
# page_data = p.page(page)
# get_page会处理一些用户输入的异常行为,而 page不会处理
page_data.object_list:这一页里的数据列表
page_data.number:当前的页码
page_data.paginator.num_pages:总共有多少页
分页处理异常:
方式三:使用ListView进行分页(基于面向对象的方式)
views.py:
class UserListView(ListView):
# 配置模板
template_name = 'user_list_class.html'
# 配置要分页的对象
model = User
# 每页放多少条数据
paginate_by = 20
# 分页传递的参数(?page=1),默认是page
page_kwarg = 'p'
urls.py:
path('user/list/class', views.UserListView.as_view(),name='...')
user_list_class.html:
page_obj:分页数据,如页码,当前第几页
object_list:当前页的数据列表
使用aggregate从整个查询结果集生成统计数据
返回一个结果
Grade.objects.all().aggregate(Avg(‘score’))
{‘score__avg’: xxx}
指定别名
Grade.objects.all().aggregate(avg=Avg(‘score’))
{‘avg’: xxx}
使用annotate为查询结果集中的每一项生成统计数据
在列表中使用,返回多个结果
Student.objects.all().annotate(Sum(‘stu_grade__score’))
{‘stu_grade__score__sum’:xxx}
指定别名
Student.objects.all().annotate(total=Sum(‘stu_grade__score’))
{‘total’:xxx}
多个线程同时对资源进行操作时而造成数据不一致
UPDATE grade SET 'score' = 800 -> UPDATE grade SET 'score' = 'score' + 1
grade_obj.score = F('score') + 1
事务使用场景:
一.自动提交
使用装饰器:
@transaction.atomic()
def view(request):
# 事务内代码
do_stuff()
过程解析:
使用with语法:
def view(request):
with transaction.atomic():
# 事务内代码
do_stuff()
二.手动提交和回滚
使用try,except捕捉异常后不会触发事务自动回滚的操作,故需要手动提交和回滚事务。
try:
a.save()
b.save()
# 放弃自动提交事务
transaction.set_autocommit(False)
# 提交事务
transaction.commit()
except Exception as e:
print(e)
# 事务回滚
transaction.rollback()