数据库迁移文件混乱的解决方法
数据库中django_migrations表记录了migrate的‘全过程’,项目各应用中的migrate文件与之对应,否则migrate会报错
解决方案:
1、删除所有migrations里所有的000?_xxxx.py(__init__.py除外)
2、删除数据库。
3、重新创建数据库
4、重新生成migrations里所有的000?_xxxx.py
python3 manage.py makemigrations
5、重新更新数据库
python3 manage.py migrate
ORM-操作-创建(插入)数据
ORM CRUD核心 -> 模型类.
管理器对象
管理器对象
每个继承自models.Model的模型类,都会有一个objects对象被同样继承下来。
Django ORM使用一种直观的方式把数据库表中的数据表示成python对象
创建数据中每一条记录就是创建一个数据对象
方案1
MyModel.objects.create(属性1=值1,属性2=值1,...)——
属性即字段
成功:返回创建好的实体对象
失败:抛出异常
代码示例
方案2
创建MyModel实例对象,并调用save()进行保存
obj = MyModel(属性=值,属性=值)——
属性即字段
obj.属性=值
obj.save()
Django Shell
ORM—查询数据操作
更多案例参考官方文档:
https://docs.djangoproject.com/zh-hans/2.2/ref/models/querysets/#field-lookups
all()方法——输出所有字段值
案例1:
案例2:格式化输出
可以在模型类中定义__str__方法,自定义QuerySet中的输出格式
例如 在Book模型类下定义如下:
则在Django shell中可得到如下显示输出
案例3:values('列1','列2'..)——输出
指定
字段
案例4:values_list('列1','列2'...)
案例5:order_by()——排序
组合排序
转换SQL语句
练习1:
1、在应用下创建视图函数
2、创建HTML文件生成表格,并引入模型类数据
3、在主路由进行路由分发
4、在应用下创建子路由文件
5、最后查看
条件查询-方法
filter(条件)——过滤筛选
filter案例
当多个属性在一起时为"与"关系
exclude(条件)——取非
排除掉清华大学出版社
get(条件)
异常案例:出现多条结果
异常案例:查询不到数据
正常显示:一条数据
非等值查询
查询谓词
查询id大于3的数据
转换成SQL语句
更新数据
更新单个数据
案例:修改id为1,price字段的值
批量更新数据
练习2-制作更新书籍的页面
点击“查看所有书籍”页面中的‘更新’进入更新页面
视图函数update_book
url http://127.0.0.1:8000/bookstore/update_book/<book_id>
更新页中显示当前书籍信息,且能对定价和零售价进行修改
views.py
def update_book(request,book_id):
#bookstore/update_book/1
try:
book = Book.objects.get(id=book_id)
except Exception as e:
print('--update book error is %s'%(e))
return HttpResponse('--The book is not exitsted')
if request.method == 'GET':
return render(request,'bookstore/update_book.html',locals())
elif request.method == 'POST':
price = request.POST['price']
market_price = request.POST['market_price']
#改
book.price = price
book.market_price = market_price
#保存
book.save()
return HttpResponseRedirect('/bookstore/all_book')
update_book.html
<body>
<form action="/bookstore/update_book/{{ book.id }}" method="post">
<P>
title <input type="text" value="{{ book.title }}" disabled="disabled">
</P>
<p>
pub <input type="text" value="{{ book.pub }}" disabled="disabled">
</p>
<p>
price <input type="text" name="price" value="{{ book.price }}">
</p>
<p>
market_price <input type="text" name="market_price" value="{{ book.market_price }}">
</p>
<p>
<input type="submit" value="更新">
</p>
</form>
</body>
单个数据删除
删除单个案例:
批量删除
伪删除
练习3-制作“删除书籍”的页面
views.py
F对象和Q对象
F对象
一个F对象代表数据库中的
某条记录的字段的信息。
作用:
通常是对数据库中的
字段值在不获取的情况下进行操作
用于类属性(字段)之间的比较
语法:
案例-查询零售价大于定价的书籍
案例2-比较
结论:传统的方法需要取出值才能比较,F对象则省略取值步骤直接比较,效率高。
Q对象
当在获取查询结果集 使用复杂的
逻辑或 |、逻辑非~ 等操作时可以借助与Q对象进行操作。
作用 在条件中用来实现除and(&)以外的or(|)或not(~)操作
案例:
总结
F对象——标记字段
Q对象——或与非
聚合查询和原生数据库操作
ROM聚合查询
聚合查询是指对一个数据表中的一个字段的数据进行部分或者全部进行统计查询,查bookstore_book数据表中的全部书的平均价格,查询所有书的总个数等,都要使用聚合查询。
聚合查询分为:
整表聚合
不带分组的聚合查询是指导将全部数据进行集中统计查询
分组聚合
分组聚合是通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。
通过返回结果的QuerySet.annotate方法分组聚合得到分组结果
QuerySet.annotate(别名=聚合函数('列名'))
原生数据库操作
SQL注入
使用原生语句时小心SQL注入
定义:用户通过数据上传,将恶意SQL语句提交给服务器,从而达到攻击效果
SQL注入防范
原生数据库操作-cursor
完全跨过模型类操作数据库-查询/更新/删除
1、导入cursor所在的包
from django.db import connection
2、用创建cursor类的构造函数创建cursor对象,在使用cursor对象。
3、为保证再出现异常时能释放cursor资源,通常使用with语句进行创建操作
示例