- # 聚合查询
- 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是我们自己定义的字段 用来存储统计出来的每本书对应的作者个数
- 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)
- CharField()
- max_length=
-
- InterFiled()
-
- DateField()
- auto_now 每次修改记录的时候都会修改时间
- auto_now_add 只在创建数据的时候记录创建时间后续不在改动
-
- AutoField
- 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该方法内部就是子查询
- 将子查询出来的所有结果也给你封装到对象中
- 给你的感觉也好像是一次性搞定
- '''
- 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
\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')
-
- 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
- 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这四个方法
- """
- # 你需要掌握的是全自动和半自动为了扩展性更高,一般我们会采用半自动
- """
- 异步提交
- 局部刷新
- 例子: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里面配置一个参数
- (后面再讲)
- """