django框架|django框架——模型层(上)

系列文章目录 第一章 django安装与介绍
第二章 django基础使用
第三章 路由层
第四章 虚拟环境、django版本区别、视图层
第五章 模板层
第六章 模型层(上)

文章目录

  • 系列文章目录
  • django测试环境搭建
  • 查看SQL语句
  • 一、orm常用字段以及重要参数
  • 二、查询
    • 1.all()
    • 2.filter(**kwargs)
    • 3.get(**kwargs)
    • 4.exclude(**kwargs)
    • 5.values(*field)
    • 6.values_list(*field)
    • 7.order_by(*field)
    • 8.reverse()
    • 9.distinct()
    • 10. count()
    • 11.first()
    • 12.last()
    • 13.exists()
  • 三、双下划线查询
  • 四、创建外键关系
    • 1.一对一关系
    • 2.一对多关系
    • 3.多对多关系
  • 五、外键字段的增删改
    • 1.增
    • 2.改
    • 3.删
  • 六、正反向的概念
  • 七、多表查询
    • 1.子查询
    • 2.连表操作

django测试环境搭建 1.创建任意py文件
2.py文件中加上固定的测试环境
from django.test import TestCase import osif __name__ == "__main__": # os.environ.setdefault("DJANGO_SETTINGS_MODULE", "项目文件.settings文件") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djtest.settings") import djangodjango.setup() #在此处开始编写测试代码

除了使用测试文件测试之外还可以是使用pycharm提供的测试环境来测试。
点击左下方的python console在其中直接编写测试代码即可
查看SQL语句 方式1:如果结果集对象是queryset 那么可以直接点query查看
方式2:配置文件固定配置
LOGGING = { 'version': 1, 'disable_existing_loggers': False, 'handlers': { 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', }, }, 'loggers': { 'django.db.backends': { 'handlers': ['console'], 'propagate': True, 'level':'DEBUG', }, } }

一、orm常用字段以及重要参数 字段
AutoField
int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。
IntegerField
一个整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)
CharField
字符类型,必须提供max_length参数, max_length表示字符长度。
DateField
日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。
DateTimeField
日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。
DecimalField
浮点型字段,max_digits数字允许的最大位数,decimal_places小数的最大位数
BigIntergerField
对应mysql的bigintterger类型
BooleanField
存储的值在python对应False和True,但存在数据库中为1或0,使用时会自动将数据库中的0或1转换为布尔值
TextField
存储大段文本
FileField
传文件自动保存到指定位置然后数据库中存储相应的文件路径
EmailField
在mysql中本质还是varchar类型 ,知识在python中会自动检测输入的字符串是否符合邮箱格式
自定义字段
在模型层中每一个字段实际上都是一个python类,自定义字段就是自定义python类来继承django自己的字段类,自定义字段中可以设计新方法,也可以继承Field中的方法然后重写
eg:
class MyCharField(models.Field): def __init__(self, max_length, *args, **kwargs): self.max_length = max_length super().__init__(max_length=max_length, *args, **kwargs)def db_type(self, connection): # 返回该字段在数据库中的类型,除此之外还有别的方法

参数
primary_key
用于设置主键primary_key = True
max_length
用于设置字段长度max_length=20
verbose_name
用于外键字段设置正向查询的名称verbose_name = “fk1”
null
设置字段是否可以为空null = True
default
设置字段默认值default = 5
max_digits
数字允许的最大位数max_digits=5
decimal_places
小数允许的最大位数decimal_places=4
unique
是否设置唯一unique=True
db_index
设置为索引db_index = True
auto_now
每次修改字段所在表,字段值自动更新为修改时间auto_now = True
auto_now_add
第一次添加记录时,字段值变为添加时间auto_now_add = True
choices
用于可以被列举完全的数据
eg:
class User(models.Model): username = models.CharField(max_length=30) password = models.CharField(max_length=16) gender_choice = ( # gender_choice 可以随意取名 (1,'男性'), (2,'女性'), (3,'无') ) gender = models.IntegerField(choices=gender_choice) #在需要使用的位置choice参数绑定之前创建的choiceUser.gender # 获取user表的所有gender数据库中的值 也就是1,2,3 User.get_gender_display()# 获取user表的所有gender我们自己设定的代表值 也就是男性,女性,无

二、查询 1.all() 查询所有结果,返回的结果是QuerySet对象
res = models.User.objects.all()

2.filter(**kwargs) 它包含了与所给筛选条件相匹配的对象,返回的结果是QuerySet对象
res = models.User.objects.filter()

3.get(**kwargs) 返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误,返回的结果为具体的对象
res = models.User.objects.get(uid=2)

4.exclude(**kwargs) 它包含了与所给筛选条件不匹配的对象,返回的结果是QuerySet对象
res = models.User.objects.exclude(uid=2)

5.values(*field) 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列
res = models.User.objects.values("uid", "name", "age")

6.values_list(*field) 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
res = models.User.objects.values_list("name")

7.order_by(*field) 对查询结果排序,返回的是QuerySet对象
res = models.User.objects.all().order_by("uid", "name")

8.reverse() 对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用,返回的是QuerySet对象
res = models.User.objects.all().reverse("uid")

9.distinct() 从返回结果中剔除重复纪录,筛选记录时如果有主键不会生效,返回的是QuerySet对象
res = models.User.objects.values("age").distinct()

10. count() 返回数据库中匹配查询(QuerySet)的对象数量,返回的是数字
res = models.User.objects.all().count()

11.first() 返回第一条记录,返回的是具体的对象
res = models.User.objects.all().first()

12.last() 返回最后一条记录,返回的是具体的对象
res = models.User.objects.all().last()

13.exists() 如果QuerySet包含数据,就返回True,否则返回False
res = models.User.objects.filter("uid=100").exists()

三、双下划线查询 使用方法:
属性+对应的双下查询即可
eg:
models.User.objects.filter(uid_gt=4) 查询用户id大于4的用户
__gt 大于
__lt 小于
__gte 大于等于
__lte 小于等于
__in 成员运算 如[1,2,3]表示在1或2或3
__range 范围查询 如[1,2]表示在1~2之间包含1、2
__contains 模糊查询区分大小写
__icontains 模糊查询忽略大小写
__isnull 判断是否为空 此处使用示例: 属性__isnull=True/False
__startswith 由任意字符串开头的
__endswith 由任意字符串结尾的
__regex 用来书写正则的
__year 按照年份筛选数据
__month 按照月份筛选数据
四、创建外键关系 在django1.x版本中外键是自带级联删除的
在2.x以及3.x是需要自行设置的
on_delete
当删除关联表中的数据时,当前表与其关联的行的行为。删除关联数据,与之关联也删除
设置方式 on_delete = models.CASCADE
生成外键是会在对应的表中新增一个字段,该字段一般为外键变量加上_id组成字段名来存储
以下为表的结构
class UserData(models.Model): createTime = models.DateTimeField(auto_now_add=True) updateTime = models.DateTimeField(auto_now=True)class Press(models.Model): pid = models.AutoField(primary_key=True) pname = models.CharField(max_length=20) addres = models.CharField(max_length=20)class Book(models.Model): bid = models.AutoField(primary_key=True) bname = models.CharField(max_length=20)class User(models.Model): uid = models.AutoField(primary_key=True) username = models.CharField(max_length=20) password = models.CharField(max_length=16)

1.一对一关系 使用OneToOneField来设定,一对一关系外键可以设置在任意表,但最好设置在经常访问的表
class User(models.Model): uid = models.AutoField(primary_key=True) username = models.CharField(max_length=20) password = models.CharField(max_length=16) userdata = https://www.it610.com/article/models.OneToOneField(UserData,# 此参数为连接的表 on_delete=models.CASCADE) # 级联删除

2.一对多关系 【django框架|django框架——模型层(上)】使用ForeignKey来设定,一对多关系外键设置在多的表
uid = models.AutoField(primary_key=True) username = models.CharField(max_length=20) password = models.CharField(max_length=16) press = models.ForeignKey(Press)

3.多对多关系 使用ManyToManyField来设定,多对多关系外键可以随意设置在任意表,多对多关系django会自动生成一个关系表来储存关系
class User(models.Model): uid = models.AutoField(primary_key=True) username = models.CharField(max_length=20) password = models.CharField(max_length=16) book = models.ManyToManyField(Book)

生成的关系表
django框架|django框架——模型层(上)
文章图片

五、外键字段的增删改 1.增 向book表增加新书,由于book有外键参照了press表
# 针对于一对一或者一对多时 pobj = models.Press.objects.filter(pid=1).first() models.User.objects.create(bname="图书3", press_id=1)# 此处向外键传值可以是press_id传对应press表的pid,或者是press=pobj# 针对多对多时 bobj = models.Book.objects.filter(pid=1).first() bobj.press.add() # 参数是press对象数据或者对应的主键值,可以是一个或者多个

2.改 修改book的记录
# 针对于一对一或者一对多时 pobj = models.Press.objects.filter(pid=1) models.Book.objects.update(bname="图书3", press_id=1)# 此处向外键传值可以是press_id传对应press表的pid,或者是press=pobj# 针对于多对多时 bobj = models.Book.objects.filter(bid=1) bobj.press.set()# 传一个可迭代对象

3.删
# 针对于一对一或者一对多时 pobj = models.Press.objects.filter(pid=1).first() models.Book.objects.filter(bname="图书3", press_id=1).delete()# 此处filter中外键的部分可以是press主键值或者press数据对象# 针对多对多时 bobj = models.Press.objects.filter(bid=1) bobj.press.remove() # 括号内可以放主键值也可以放数据对象 并且都支持多个 bobj.press.clear() #括号内无需传值 直接清空当前表在第三张关系表中的绑定记录

六、正反向的概念 核心在于当前数据对象是否含有外键字段 有则是正向 没有则是反向
eg:
class Press(models.Model): pid = models.AutoField(primary_key=True) pname = models.CharField(max_length=20) addres = models.CharField(max_length=20)class Book(models.Model): bid = models.AutoField(primary_key=True) bname = models.CharField(max_length=20) press = models.ForeignKey(Press)# 针对上述俩张表,如果从book查找此时是正向,这个时候查询按外键字段名,如果此press查询,这个时候查询按表名小写

七、多表查询 1.子查询 基于对象的跨表查询本质就是子查询即分步操作即可
1.先找到第一个表对象
2.表对象点外键属性
eg:
查询出版社id1所属的图书
pobj = models.Press.objects.filter(pid=1).firest() # 此时查询的俩张表,外键在book所以是反向查询,如果查询到的结果为none接在表名后加上_set res = pobj.book_set # 如果此时还是none 说明查询结果不是单个需要使用.all() res = pobj.book_set.all()

2.连表操作 基于双下划线的跨表查询本质就是连表操作
eg:
res = models.Book.objects.filter(pname='北方社区').values('press__pname', 'press__addr') # 使用表__属性名 可以获取外键表的字段

    推荐阅读