今日考题
1.聚合查询和分组查询的关键字是什么?各有什么注意事项?
# 聚合查询
aggregrate
只要是跟数据库相关的模块一般都在django.db.models
from django.db.models import Max,Min,Avg,Sum,Count
聚合查询通常都是配合分组一起使用的
# 查询所有书的平均价格
res = models.Book.onjects.aggregrate(Avg('price'))
print(res)
# 分组查询
annotate
# 统计每一本书的作者个数
res = models.Book.object.annotate(author_num=Count('authors')).values('title','author_num')
print(res)
models后面点书就按照书分组,author_num是我们自己定义的字段 用来存储统计出来的每本书对应的作者个数
2.F与Q查询的功能,他们的导入语句是什么,针对Q有没有其他的用法
from django.db.models import F
能够帮助你直接获取表中的某个数据
# 查询卖出数大于库存数的书籍
models.Book.objects.filter(mauchu__gt=F('kucun')).first()
# 将所有书籍价格提高500
models.Book.objects.update(F('price')+500)
# 将所有书的名字都打上爆款两字
from django.db.models import Value
from django.db.models.functions import Concat
models.Book.objects.update(title=Concat(F('title'),Value('爆款')))
Q查询
from django.db.models import Q
models.Book.objects.filter(Q(maichu__gt=800),Q(kuncun__lt=600))
models.Book.objects.filter(Q(maichu__gt=800)|Q(kuncun__lt=600))
models.Book.objects.filter(Q(maichu__gt=800),Q(kuncun__lt=600))
Q的高阶用法
q=Q()
q.children.append('maichu__gt',800)
q.children.append('kucun__lt',600)
models.Book.objects.filter(q)
3.列举常见的数据字段及主要参数(越多越好)
CharField()
max_length=
InterFiled()
DateField()
auto_now 每次修改记录的时候都会修改时间
auto_now_add 只在创建数据的时候记录创建时间后续不在改动
AutoField
4.orm数据库查询优化有那些?各有什么特点?
orm 语句特点是:惰性查询,如果你只是书写了orm语句后面并没有用到该语句查询出来的参数 那么orm语句会自动识别 不执行
# 获取书籍表中所有书的名字
res = models.Book.objects.only('title')
for i in res:
print(i.title) # 不会重新走数据库
print(i.price) # 需要重新走数据库查询
defer刚好与only相反,括号内的字段需要重新走数据库查询,外的字段不需要
res = models.Book.objects.all() # 每循环一次就要走一次数据库查询
# for i in res:
# print(i.publish.name)
res = models.Book.objects.select_relate('publish')
'''
select_related内部现将book与publish连起来 然后将大表里面的所有数据对象全部封装给查询出来的对象
这个时候对象无论是点击book表中的数据还是publish表中的数据都无需再走数据库查询 网络请求越少延迟越低 也就是优化数据库查询
select_related括号内只能放外键字段 一对一 一对多 多对多也不行
'''
res = models.Book.objects.prefetch_relate('publish')
'''
prefetch_related该方法内部就是子查询
将子查询出来的所有结果也给你封装到对象中
给你的感觉也好像是一次性搞定
'''
今日内容概要
- 图书管理的增删改查
- choices参数(数据库字段设计常见)
- MTV与MVC模型
- 多对多关系的三种创建方式
- Ajax操作(重点)
- 前后端传送数据编码格式
- ajax发送json格式数据
- ajax发送文件
- django自带的序列化功能
- ajax结合sweetalert实现删除的二次确认操作
今日内容详细
图书管理的增删改查
from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
# 首页
url(r'^$',views.home,name='home'),
# 图书的展示页面
url(r'^book/list/',views.book_list,name='book_list'),
# 书籍的添加
url(r'^book/add/',views.book_add,name='book_add'),
# 书籍的编辑(有名分组用来拿到当前对象id)
url(r'^book/edit/(?P<edit_id>\d+)',views.book_edit,name='book_id'),
# 书籍的删除(无名分组用来拿当前对象id)
url(r'^book/delete/(\d+)',views.book_delete,name='book_delete'),
]
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
# Create your views here.
def home(request):
return render(request,'home.html')
def book_list(request):
# 先查询出所有书籍信息 传递给html页面
book_obj = models.Book.objects.all()
return render(request,'book_list.html',locals())
def book_add(request):
if request.method=='POST':
# 获取前端提交过来的所有数据
title = request.POST.get('title')
price = request.POST.get('price')
publish_date = request.POST.get('publish_date')
publish_id = request.POST.get('publish')
authors_list = request.POST.getlist('authors')
# 操作数据库存储数据
# 书籍表
book_obj = models.Book.objects.create(title=title,price=price,publish_date=publish_date,publish_id=publish_id)
# 书籍与作者的关系表
book_obj.authors.add(*authors_list)
# 跳转到书籍展示页面
'''
redirect括号内可以直接写url 其实也可以写别名
但是如果你的别名需要额外传参的话,那么就必须使用reverse()解析
'''
return redirect('book_list')
publish_obj = models.Publish.objects.all()
authors_obj = models.Author.objects.all()
return render(request,'book_add.html',locals())
def book_edit(request,edit_id):
# 测试是否获取当前对象id值
# return HttpResponse(edit_id)
# 获取当前用户想要编辑的数据对象 展示个用户看
edit_obj = models.Book.objects.filter(pk=edit_id).first()
publish_obj = models.Publish.objects.all()
authors_obj = models.Author.objects.all()
# 向数据提交数据
if request.method == 'POST':
# 获取前端提交过来的所有数据
title = request.POST.get('title')
price = request.POST.get('price')
publish_date = request.POST.get('publish_date')
publish_id = request.POST.get('publish')
authors_list = request.POST.getlist('authors')
# 操作数据库存储数据
# 编辑书籍表
models.Book.objects.filter(pk=edit_id).update(title=title,
price=price,
publish_date=publish_date,
publish_id=publish_id
)
# 书籍与作者的关系表
edit_obj.authors.set(authors_list)
# 跳转到书籍展示页面
return redirect('book_list')
return render(request,'book_edit.html',locals())
def book_delete(request,delete_id):
# 直接删除
models.Book.objects.filter(pk=delete_id).delete()
return redirect('book_list')
choices参数(数据库字段设计常见)
class User(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
# 性别
gender_choices = (
(1,'男'),
(2,'女'),
(3,'其他'),
)
gender = models.IntegerField(choices=gender_choices)
'''
该gender字段存的还是数字,只不过数字对应元组关系。如果存的数字在上面元组列举的范围内,那么可以轻松获取到数字对应的内容
1.gender字段存的数字不在上述元组列举的范围内容
2.如果在 如果获取中文信息
'''
MTV与MCV模型
# MTV
django号称是MTV模型
M:models
T:templates
V:views
# MCV
django的本质也是MVC
M:models
C:controller
V:views
多对多关系的三种创建方式
# 自动
class Book(models.Model):
name = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author')
class Author(models.Model):
name = models.CharField(max_length=32)
'''
优点:代码不需要你写,支持orm提供的操作第三方表关系
缺点:扩展性极差(没办法额外添加字段)
'''
# 手动
class Author(models.Model):
name = models.CharField(max_length=32)
class Book(models.Model):
name = models.CharField(max_length=32)
class Book2Author(models.Model):
book_id = models.ForeignKey(to='Book')
author_id=models.ForeignKey(to='Author')
'''
第三方表完全取决你自己额外扩展
写的代码较多,并且不支持orm提供的简单方法操作第三方表
'''
# 半自动
class Book(models.Model):
name = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author',
through='Book2Author',
through_fields=('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')
'''
"""
through_fields字段先后顺序
判断的本质:
通过第三张表查询对应的表 需要用到哪个字段就把哪个字段放前面
你也可以简化判断
当前表是谁 就把对应的关联字段放前面
半自动:可以使用orm的正反向查询 但是没法使用add,set,remove,clear这四个方法
"""
# 你需要掌握的是全自动和半自动为了扩展性更高,一般我们会采用半自动
Ajax
"""
异步提交
局部刷新
例子:github注册
动态获取用户名实时的跟后端确认并实时展示的前端(局部刷新)
朝发送请求的方式
1.浏览器地址栏直接输入url回车 GET请求
2.a标签href属性 GET请求
3.form表单 GET请求/POST请求
4.ajax GET请求/POST请求
AJAX 不是新的编程语言,而是一种使用现有标准的新方法(比较装饰器)
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。(这一特点给用户的感受是在不知不觉中完成请求和响应过程)
Ajax我们只学习jQuery封装之后的版本(不学原生的 原生的复杂并且在实际项目中也一般不用)
所以我们在前端页面使用ajax的时候需要确保导入了jQuery
ps:并不只有jQuery能够实现ajax,其他的框架也可以 但是换汤不换药 原理是一样的
"""
小例子
"""
页面上有三个input框
在前两个框中输入数字 点击按钮 朝后端发送ajax请求
后端计算出结果 再返回给前端动态展示的到第三个input框中
(整个过程页面不准有刷新,也不能在前端计算)
"""
$('#btn').click(function () {
// 朝后端发送ajax请求
$.ajax({
// 1.指定朝哪个后端发送ajax请求
url:'', // 不写就是朝当前地址提交
// 2.请求方式
type:'post', // 不指定默认就是get 都是小写
// 3.数据
{#data:{'username':'jason','password':123},#}
data:{'i1':$('#d1').val(),'i2':$('#d2').val()},
// 4.回调函数:当后端给你返回结果的时候会自动触发 args接受后端的返回结果
success:function (args) {
{#alert(args) // 通过DOM操作动态渲染到第三个input里面#}
{#$('#d3').val(args)#}
console.log(typeof args)
}
})
})
"""
针对后端如果是用HttpResponse返回的数据 回调函数不会自动帮你反序列化
如果后端直接用的是JsonResponse返回的数据 回调函数会自动帮你反序列化
HttpResponse解决方式
1.自己在前端利用JSON.parse()
2.在ajax里面配置一个参数
(后面再讲)
"""
|