今日考题

"""
今日考题
1.聚合查询,分组查询的关键字各是什么,各有什么特点或者注意事项
2.F与Q查询的功能,他们的导入语句是什么,针对Q有没有其他用法
3.列举常见的数据库字段及主要参数(越多越好)
4.orm数据库查询优化相关有哪些各有什么特点
"""

昨日内容回顾

在学习django orm的时候,最好自己复习一下MySQL相关的知识点,不要造成大面积的遗忘

  • 聚合查询

    # 单独使用的时候 需要借助于关键字		aggregate
    from django.db.models import Max,Min,Sum,Count,Avg
    aggregate(Max('age'),Min('price'),...)
  • 分组查询

    # 分组报错确保代码没有写错的情况下 需要去修改严格模式		annotate
    
    models.Book.objects.annotate()  # models后面点什么就是按照上面分组
    
    models.Book.objects.values('字段').annotate()  # values出现在了annotate的前面,那么就按照values括号内指定的字段分组
  • F与Q查询

    from django.db.models import F,Q
    # F查询:能够获取到表中指定字段对应的数据
    1.库存大于卖出
    2.所有的商品价格提高500块
    3.所有商品名称后面加爆款
    针对字符类型,在做拼接的时候需要额外的导入模块Concat,Value # Q查询:能够改变多个查询条件之间的关系 与或非
    # 基本使用
    filter(Q(),Q()) # and
    filter(Q()|Q()) # or
    filter(~Q()|Q()) # not # 高阶使用
    """
    我们之前在查询数据的时候,条件的左边都是变量名的形式
    如何做到左边也是字符串的形式呢?(动态的指定查询的条件)
    """
    q = Q() # q默认多个条件之间还是and关系
    q.connector = 'or' # 可以修改链接关系
    q.children.append(('price',123))
    q.children.append(('title','三国演义'))
    filter(q)
  • orm事务操作

    """
    事务四大特性
    ACID
    数据库三大设计范式(自己百度搜索,自己整理)
    https://www.cnblogs.com/linjiqin/archive/2012/04/01/2428695.html
    """
    from django.db import transaction
    try:
    with transaction.atomic():
    pass
    # with代码块里面所有的orm操作都属于同一个事务
    except Exception as e:
    print(e)
  • 常用字段

    # 所有的字段都有一个verbose_name参数 用来对字段继续描述
    AutoField
    -primary_key CharField
    -max_length IntegerField
    BigintegerField DecimalField
    -max_digits
    -decimal_places DateField
    DateTimeField
    -auto_now:修改
    -auto_now_add:新建 EmailField BooleanField
    传布尔值 存0/1 TextField
    存大段文本(博客、日记、文章...) FileField
    -upload_to
    可以指定文件的存放位置,该字段只存文件的路径 # 其他的字段 自己参考博客了解 # 外键字段及参数
    to
    to_field
    on_delete
    db_index
    # 了解 一对一其实可以有两种指定方式
    OneToOneField()
    ForeginKey(unique=True) 不推荐
    # django不同 级联更新级联删除可能需要自己指定
    ... # 还支持自定义字段
    class MyCharField(models.Field):
    def __init__(...):
    ... def db_type(...):
    ...
    username = MyCharField(...)
  • 数据库优化

    # only与defer
    """
    only
    结果是一个列表套多个对象,这些对象默认只有only括号内的属性
    但是也可以点击括号内没有的属性,但是需要额外的走数据库操作
    defer
    跟only刚好相反
    对象里面唯独没有括号内指定的属性
    """ # select_related与prefetch_related
    """
    select_related内部的本质是联表操作 inner join
    括号内只能放外键字段并且多对多不行
    括号内可以放多个外键字段
    select_related(外键字段1__外键字段2__外键字段3__...)
    将联表之后的结果全部查询出来封装到对象里面
    之后对象在点击表的字段的时候都无需再走数据库 prefetch_related内部本质是子查询
    内部通过子查询的方式将多张的表数据也封装到对象中
    这样用户在使用的时候也是感觉不出来的 上述两种方式,在不同的场景下效率各有千秋
    only和defer的选择,看字段个数,单个字段的数据多少
    select_relate与prefetch_relate选择,看连表时间长还是额外访问数据库时间长
    """
  • 图书管理系统首页搭建

    # 首页搭建
    
    # 模版的制作

今日内容概要

  • 图书管理的图书增删改查
  • choices参数(数据库字段设计常见)
  • MTV与MVC模型
  • 多对多关系的三种创建方式
  • Ajax操作(重点)

今日内容详细

图书管理的图书增删改查

from django.shortcuts import render,redirect,HttpResponse
from app01 import models
# Create your views here. #首页
def home(request):
return render(request,'home.html') #展示书籍列表
def book_list(request):
#先查询楚所有的书籍信息传递给html页面
book_queryset = 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") #这里拿到的是列表套数据 [1,2,3,4]
#操作数据库存储数据
#书籍表
book_obj = models.Book.objects.create(title=title,price=price,publish_data=publish_date,publish_id=publish_id)
#书籍和作者的关系表 这是自动创建的第三张表正常情况下无法操作
# 但是上面的书籍表的create方法会返回一个当前被创建的书籍对象 刚刚好
book_obj.authors.add(*authors_list) #直接将列表打散 变成1,2,3,4 因为add方法添加多个参数的时候需要这个格式
"""
redirect括号内可以直接写url
其实也可以直接写别名 但是你的别名需要额外给参数的话,那么就必须使用reverse解析了
"""
#跳转到书籍的展示页面
return redirect('book_list') #先获取当前出版社中所有的出版社信息和作者信息
publish_queryset = models.Publish.objects.all()
author_queryset = models.Author.objects.all()
return render(request, 'book_add.html',locals()) #书籍的编辑
def book_edit(request,edit_id):
# 获取当前用户想要编辑的书籍对象,展示给用户看
edit_obj = models.Book.objects.filter(pk=edit_id).first()
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") # 这里拿到的是列表套数据 [1,2,3,4]
# 操作数据库存储数据
# 书籍表
book_obj = models.Book.objects.filter(pk=edit_id).update(title=title,
price=price,
publish_data=publish_date,
publish_id=publish_id)
# 第三张关系表
edit_obj.authors.set(authors_list) #这里前面不加* 因为set需要的就是一个可迭代对象
# 跳转到书籍的展示页面
return redirect('book_list') #获取当前出版社中所有的出版社信息和作者信息
publish_queryset = models.Publish.objects.all()
author_queryset = models.Author.objects.all()
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):
username = models.CharField(max_length=32)
age = models.IntegerField()
# 性别
gender_choices = (
(1, '男'),
(2, '女'),
(3, '其他'),
)
gender = models.IntegerField(choices=gender_choices) score_choices = (
('A', '优秀'),
('B', '良好'),
('C', '及格'),
('D', '不合格'),
)
#保证字段类型跟列举出来的元祖第一个数据类型一致即可
score = models.CharField(choices=score_choices, null=True)
"""
该gender字段存的还是数字 但是如果存的数字在上面元祖列举的范围之内
那么可以非常轻松的获取到数字对应的真正的内容 1.gender字段存的数字不在上述元祖列举的范围内容
存的时候 没有列举出来的数字也能存
取的时候 如果没有对应关系 那么字段是什么 还返回什么
2.如果在 如何获取对应的中文信息
只要是choices参数的字段 如果你想要获取对应的信息 固定写法:get_字段名_display()
print(user_obj.get_gender_display()) 输出男
""" # 实际项目案例
# CRM相关内部表
class School(models.Model):
"""
校区表
如:
北京沙河校区
上海校区 """
title = models.CharField(verbose_name='校区名称', max_length=32) def __str__(self):
return self.title class Course(models.Model):
"""
课程表
如:
Linux基础
Linux架构师
Python自动化开发精英班
Python自动化开发架构师班
Python基础班
go基础班
"""
name = models.CharField(verbose_name='课程名称', max_length=32) def __str__(self):
return self.name class Department(models.Model):
"""
部门表
市场部 1000
销售 1001 """
title = models.CharField(verbose_name='部门名称', max_length=16)
code = models.IntegerField(verbose_name='部门编号', unique=True, null=False) def __str__(self):
return self.title class UserInfo(models.Model):
"""
员工表
""" name = models.CharField(verbose_name='员工姓名', max_length=16)
email = models.EmailField(verbose_name='邮箱', max_length=64)
depart = models.ForeignKey(verbose_name='部门', to="Department",to_field="code")
user=models.OneToOneField("User",default=1)
def __str__(self):
return self.name class ClassList(models.Model):
"""
班级表
如:
Python全栈 面授班 5期 10000 2017-11-11 2018-5-11
"""
school = models.ForeignKey(verbose_name='校区', to='School')
course = models.ForeignKey(verbose_name='课程名称', to='Course')
semester = models.IntegerField(verbose_name="班级(期)") price = models.IntegerField(verbose_name="学费")
start_date = models.DateField(verbose_name="开班日期")
graduate_date = models.DateField(verbose_name="结业日期", null=True, blank=True)
memo = models.CharField(verbose_name='说明', max_length=256, blank=True, null=True, ) teachers = models.ManyToManyField(verbose_name='任课老师', to='UserInfo',limit_choices_to={'depart':1002})
tutor = models.ForeignKey(verbose_name='班主任', to='UserInfo',related_name="class_list",limit_choices_to={'depart':1006}) def __str__(self):
return "{0}({1}期)".format(self.course.name, self.semester) class Customer(models.Model):
"""
客户表
"""
qq = models.CharField(verbose_name='qq', max_length=64, unique=True, help_text='QQ号必须唯一') name = models.CharField(verbose_name='学生姓名', max_length=16)
gender_choices = ((1, '男'), (2, '女'))
gender = models.SmallIntegerField(verbose_name='性别', choices=gender_choices) education_choices = (
(1, '重点大学'),
(2, '普通本科'),
(3, '独立院校'),
(4, '民办本科'),
(5, '大专'),
(6, '民办专科'),
(7, '高中'),
(8, '其他')
)
education = models.IntegerField(verbose_name='学历', choices=education_choices, blank=True, null=True, )
graduation_school = models.CharField(verbose_name='毕业学校', max_length=64, blank=True, null=True)
major = models.CharField(verbose_name='所学专业', max_length=64, blank=True, null=True) experience_choices = [
(1, '在校生'),
(2, '应届毕业'),
(3, '半年以内'),
(4, '半年至一年'),
(5, '一年至三年'),
(6, '三年至五年'),
(7, '五年以上'),
]
experience = models.IntegerField(verbose_name='工作经验', blank=True, null=True, choices=experience_choices)
work_status_choices = [
(1, '在职'),
(2, '无业')
]
work_status = models.IntegerField(verbose_name="职业状态", choices=work_status_choices, default=1, blank=True,
null=True)
company = models.CharField(verbose_name="目前就职公司", max_length=64, blank=True, null=True)
salary = models.CharField(verbose_name="当前薪资", max_length=64, blank=True, null=True) source_choices = [
(1, "qq群"),
(2, "内部转介绍"),
(3, "官方网站"),
(4, "百度推广"),
(5, "360推广"),
(6, "搜狗推广"),
(7, "腾讯课堂"),
(8, "广点通"),
(9, "高校宣讲"),
(10, "渠道代理"),
(11, "51cto"),
(12, "智汇推"),
(13, "网盟"),
(14, "DSP"),
(15, "SEO"),
(16, "其它"),
]
source = models.SmallIntegerField('客户来源', choices=source_choices, default=1)
referral_from = models.ForeignKey(
'self',
blank=True,
null=True,
verbose_name="转介绍自学员",
help_text="若此客户是转介绍自内部学员,请在此处选择内部学员姓名",
related_name="internal_referral"
)
course = models.ManyToManyField(verbose_name="咨询课程", to="Course") status_choices = [
(1, "已报名"),
(2, "未报名")
]
status = models.IntegerField(
verbose_name="状态",
choices=status_choices,
default=2,
help_text=u"选择客户此时的状态"
) consultant = models.ForeignKey(verbose_name="课程顾问", to='UserInfo', related_name='consultanter',limit_choices_to={'depart':1001}) date = models.DateField(verbose_name="咨询日期", auto_now_add=True)
recv_date = models.DateField(verbose_name="当前课程顾问的接单日期", null=True)
last_consult_date = models.DateField(verbose_name="最后跟进日期", ) def __str__(self):
return self.name class ConsultRecord(models.Model):
"""
客户跟进记录
"""
customer = models.ForeignKey(verbose_name="所咨询客户", to='Customer')
consultant = models.ForeignKey(verbose_name="跟踪人", to='UserInfo',limit_choices_to={'depart':1001})
date = models.DateField(verbose_name="跟进日期", auto_now_add=True)
note = models.TextField(verbose_name="跟进内容...") def __str__(self):
return self.customer.name + ":" + self.consultant.name class Student(models.Model):
"""
学生表(已报名)
"""
customer = models.OneToOneField(verbose_name='客户信息', to='Customer')
class_list = models.ManyToManyField(verbose_name="已报班级", to='ClassList', blank=True) emergency_contract = models.CharField(max_length=32, blank=True, null=True, verbose_name='紧急联系人')
company = models.CharField(verbose_name='公司', max_length=128, blank=True, null=True)
location = models.CharField(max_length=64, verbose_name='所在区域', blank=True, null=True)
position = models.CharField(verbose_name='岗位', max_length=64, blank=True, null=True)
salary = models.IntegerField(verbose_name='薪资', blank=True, null=True)
welfare = models.CharField(verbose_name='福利', max_length=256, blank=True, null=True)
date = models.DateField(verbose_name='入职时间', help_text='格式yyyy-mm-dd', blank=True, null=True)
memo = models.CharField(verbose_name='备注', max_length=256, blank=True, null=True) def __str__(self):
return self.customer.name class ClassStudyRecord(models.Model):
"""
上课记录表 (班级记录)
"""
class_obj = models.ForeignKey(verbose_name="班级", to="ClassList")
day_num = models.IntegerField(verbose_name="节次", help_text=u"此处填写第几节课或第几天课程...,必须为数字")
teacher = models.ForeignKey(verbose_name="讲师", to='UserInfo',limit_choices_to={'depart':1002})
date = models.DateField(verbose_name="上课日期", auto_now_add=True) course_title = models.CharField(verbose_name='本节课程标题', max_length=64, blank=True, null=True)
course_memo = models.TextField(verbose_name='本节课程内容概要', blank=True, null=True)
has_homework = models.BooleanField(default=True, verbose_name="本节有作业")
homework_title = models.CharField(verbose_name='本节作业标题', max_length=64, blank=True, null=True)
homework_memo = models.TextField(verbose_name='作业描述', max_length=500, blank=True, null=True)
exam = models.TextField(verbose_name='踩分点', max_length=300, blank=True, null=True) def __str__(self):
return "{0} day{1}".format(self.class_obj, self.day_num) class StudentStudyRecord(models.Model):
'''
学生学习记录
'''
classstudyrecord = models.ForeignKey(verbose_name="第几天课程", to="ClassStudyRecord")
student = models.ForeignKey(verbose_name="学员", to='Student') record_choices = (('checked', "已签到"),
('vacate', "请假"),
('late', "迟到"),
('noshow', "缺勤"),
('leave_early', "早退"),
)
record = models.CharField("上课纪录", choices=record_choices, default="checked", max_length=64)
score_choices = ((100, 'A+'),
(90, 'A'),
(85, 'B+'),
(80, 'B'),
(70, 'B-'),
(60, 'C+'),
(50, 'C'),
(40, 'C-'),
(0, ' D'),
(-1, 'N/A'),
(-100, 'COPY'),
(-1000, 'FAIL'),
)
score = models.IntegerField("本节成绩", choices=score_choices, default=-1)
homework_note = models.CharField(verbose_name='作业评语', max_length=255, blank=True, null=True)
note = models.CharField(verbose_name="备注", max_length=255, blank=True, null=True) homework = models.FileField(verbose_name='作业文件', blank=True, null=True, default=None)
stu_memo = models.TextField(verbose_name='学员备注', blank=True, null=True)
date = models.DateTimeField(verbose_name='提交作业日期', auto_now_add=True) def __str__(self):
return "{0}-{1}".format(self.classstudyrecord, self.student) """
chocies参数使用场景是非常广泛的
"""

MTV与MVC模型

# MTV:Django号称是MTV模型
M:models
T:templates
V:views
# MVC:其实django本质也是MVC
M:models
V:views
C:controller # vue框架:MVVM模型

多对多三种创建方式

# 全自动:利用orm自动帮我们创建第三张关系表
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 Book(models.Model):
name = models.CharField(max_length=32) class Author(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)
console.log(args.name) }
})
}) #后端
import json
from django.http import JsonResponse
def ab_ajax(request):
if request.method == 'POST':
i1 = request.POST.get('i1')
i2 = request.POST.get('i2')
#先转成整型再加
i3 = int(i1) + int(i2)
print(i3)
#return HttpResponse(i3)
#如果想要返回一个字典 需要借助json模块中的dumps() HttpResponse只能直接返回一个数字类型的数据
# d = {'name':"ss",'code':157}
# return HttpResponse(json.dumps(d)) 这里前端接受到得还是一个string类型的 #利用JsonResponse直接将string转换为对象 然后拿里面的数据直接可以通过点的方式
d = {'name': "ss", 'code': 157}
return JsonResponse(d) return render(request,'index.html') """
针对后端如果是用HttpResponse返回的数据 回调函数不会自动帮你反序列化
如果后端直接用的是JsonResponse返回的数据 回调函数会自动帮你反序列化 HttpResponse解决方式
1.自己在前端利用JSON.parse()
2.在ajax里面配置一个参数
(后面再讲)
"""

作业

今日作业
必做题
1.整理今日内容 用自己的话术整理到博客中(切勿直接复制粘贴)
2.orm数据库查询优化及数据库三大设计范式自我归纳总结
3.体会choices参数在实际项目中的具体应用场景
选做
4.利用ajax完成数据的二次确认删除

最新文章

  1. Xcode UUID查询
  2. Codeforces 713C Sonya and Problem Wihtout a Legend
  3. Qt之加载QSS文件
  4. Shell基础:Shell和Mysql交互
  5. xss 和 csrf攻击详解
  6. 【转】Java多线程操作局部变量与全局变量
  7. jQuery相关知识
  8. Android 常用代码片小结
  9. [LeetCode]题解(python):143-Reorder List
  10. Vs2015 Ef 连接Oracle 出现OracleInternal.Common.ConfigBaseClass 的解决办法
  11. Mac和Linux系统的:Arp欺骗源码
  12. aapt不是内部命令
  13. C#设计模式之十五命令模式(Command Pattern)【行为型】
  14. ASP.NET Core使用SkiaSharp实现验证码
  15. Java基础学习(四)-- 接口、集合框架、Collection、泛型详解
  16. 教你搞定ElasticSearch(head)
  17. oracle-rman-3
  18. C#5种方式生成缩略图
  19. sublime text3 汉化
  20. (一)认识Sass和Compass

热门文章

  1. Java中解决多线程数据安全问题
  2. Build Web Server with Apache and Passenger
  3. JStorm:概念与编程模型
  4. spring security整体流程
  5. zzcms2020代码审计笔记
  6. IP网络地址的计算
  7. 题解—P2511 [HAOI2008]木棍分割
  8. 将数组对象相同key的内容合并
  9. QT中的对象模型――QPointer
  10. Mybatis轻松入门(仅要求会用看着一个就够了,略过源码分析部分即可)