这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题
于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。
微信小程序搜索: Python面试宝典
也可关注 微信公众号,不定时发送各类有趣猎奇的技术文章: Python编程学习
在进行模型操作的学习之前,可以先创建一个测试的数据库模型类,如下所示
class Person(models.Model):
name = models.CharField(max_length=10,verbose_name="姓名")
age = models.IntegerField(verbose_name="年龄")
django自带了一个数据库测试的shell工具,这是一个非常方便可以让我们对django代码进行测试的环境
可以直接通过 python manage.py shell
命令行管理工具来打开
通过模型类的关键词参数实例化一个对象来进行数据的创建
>>> from app.models import Person
>>> p1 = Person(name='张三',age=15)
>>> p1.save()
以上的代码,在为字段赋予值之后,通过实例的save函数进行该数据的保存
在数据库底层执行了 SQL
语句中的 insert
操作,并且,在我们显示调用 save
之前, django
不会访问数据库,实例数据只存在于内存中
- 注意:
save
函数没有返回值
>>> P1 = Person.objects.create(name='李四',age=20)
这条语句创建一条数据,并且返回一个数据在内存中的实例P1,之后可以通过这个实例字段P1对数据库中该条数据进行修改或删除操作
create
方法一步到位, save
方式可以慢悠悠的赋予字段值,最后赋予结束再save
接下来,我们将通过模型类中的管理器进行数据的查询;
管理器 (Manager)
是每一个模型类所具有的,默认名为 objects
,模型类通过模型类调用 orm
数据接口,其实就是在对数据表进行操作
注意,具体的某一条数据无法访问这个管理器
获取一个表中的所有数据,返回
QuerySet
数据对象
all_person = Person.objects.all()
返回一个包含数据对象的集合,满足参数中所给的条件
res = Person.objects.all().filter(age__lt=16)
res = Person.objects.filter(age__lt=16)
我们在查询过程中,除了直接使用字段属性进行验证
还可以在字段名之后使用双下化线来标明更加详细的字段筛选条件(在下一节会有详细的字段筛选条件介绍),也叫做链式过滤
这也是为什么表单类字段不可以以下换线结尾的原因
返回一个包含数据对象的集合,数据为不满足参数中所给的条件
filter()查询会始终返回一个结果集,哪怕只有一个数据,但是有些时候,我们对于一些在数据表中的唯一数据进行查询时,可以使用更加合适的 get
方法
- 注意:创建结果集的过程不涉及任何数据库的操作,查询工作是惰性的,在上面的查询方式中,查询代码不会实际访问数据库,只有查询集在真正使用时,django才会访问数据库
获取唯一单条数据
get获取数据只会返回一条匹配的结果,获取的数据只能在数据库中有一条
如果返回多个结果,会引发 MultipleObjectsReturned
异常;如果没有任何匹配到的结果也会引发 DoesNotExist
异常
Person.objects.get(pk=1)
默认情况下,数据表使用模型类中的Meta中指定的ordering选项进行排序
也可以通过使用order_by函数进行查询结果的排序
Person.objects.order_by('age')
Person.objects.all().order_by('-age')
返回数据库中对应字段的个数,并且该函数永远不会引发异常
models.Person.objects.filter(age=20).count()
Person.objects.count()
使用 count
函数时,还需要对数据表进行迭代访问
- 注意:所以有时使用已生产好的结果集,通过 len函数获取长度,这种方式效率会更高;
count
方法的调用会导致额外的数据库查询
返回一个查询集结果,但是迭代访问时返回的是字典,而不是数据实例对象
models.Person.objects.all().values()
models.Person.objects.values()
大小写敏感的匹配查询,也是like,注意转换后查询条件的两侧都有%
Person.objects.filter(name_contains='好')
大小写不敏感的匹配查询
Person.objects.filter(name_icontains='好')
在某个范围内进行查询
Person.objects.filter(id_range=(1,6))
查询条件是否在给定的范围内,用小括号和中括号都可以
Person.objects.filter(id_in=(1,6))
Person.objects.filter(id_in=[1,6])
如果在查询过程中,没有提供查询类型(没有 双下划线
),那么查询类型就会被默认指定为 exact
,这是一种严格查找的方式,用来在数据库中查找和查询时的关键词参数完全一致的内容
Person.objects.filter(account='root')
Person.objects.filter(account__exact='root')
忽略大小写的匹配
Person.objects.filter(account__iexact='root')
分别匹配开头和结尾,区分大小写
Person.objects.filter(passwd__startswith='admin')
分别匹配开头和结尾,忽略大小写
Person.objects.filter(passwd__istartswith='admin')
匹配以不区分大小写的字符串admin为开头的数据
大于或等于
Person.objects.filter(reg_data__gte=datetime.date.today)
小于或等于
Person.objects.filter(reg_data__lte=datetime.date.today)
获取到对应的数据实例之后,通过 .
的方式访问数据实例中的属性,进行数据的字段修改,修改之后通过 save方法对实例进行入库的保存
p = models.Person.objects.get(pk=1)
p.age = 21
p.save()
对过滤出的结果链式调用 update()
函数,这样的修改,类似批量修改, update
函数会返回成功修改的个数
models.Person.objects.filter(age__gt=100).update(age=25)
对于普通的单表数据删除,获取到数据实例对象后调用内置的 delete()
函数即可
models.Person.objects.get(pk=1).delete()
- 注意:删除一条数据之后,默认占有的主键ID值并不会被下一个新插入的值所占用
比如 1,2,3,4;删除掉3之后,剩下:1,2,4;下一个值存储时,id是5,3不会被复用
字段关系是 django
维护表关系的方式;其中主要有 一对一, 多对一以及 多对多
现在的 一对一及 多对一关系中需要设置 on_delete
属性用来描述当关联数据被删除时的操作
- models.CASCADE:删除关联数据,与之关联也删除
- models.PROTECT:删除关联数据,引发错误
ProtectedError
- models.SET_NULL:与之关联的值设置为
null
(前提FK
字段需要设置为可空) - models.SET_DEFAULT:删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)
- models.DO_NOTHING:删除关联数据,什么也不做
模型类使用
OneToOneField
用来定义一对一关系;
比如当你拥有一个老师表时,紧接着你还需要一个教授表,那么教授表可能拥有老师表的一系列属性,那么你还不想把老师表中的字段直接复制到教授表那么可以通过 OnToOneField
来实现教授表继承老师表。
- 注意:在使用模型类继承时,也隐含有一个一对一关系
OneToOneField(to, on_delete, parent_link=False, options)
class Teacher(models.Model):
name = models.CharField(max_length=50)
age = models.CharField(max_length=50)
def __str__(self):
return self.name
class Professor(models.Model):
teacher = models.OneToOneField(Teacher,primary_key=True,on_delete=models.CASCADE)
big_project = models.CharField(max_length=50)
def __str__(self):
return self.teacher.name
>>> t1 = Teacher.objects.create(name='Jack',age='22')
>>> t2 = Teacher.objects.create(name='Bob',age='17')
>>> p1 = Professor.objects.create(teacher=t1,big_project='雾霾净化术')
>>> p1.teacher
<Teacher: Jack>
>>> p1.teacher = t2
>>> p1.save()
>>> p1.teacher
<Teacher: Bob>
在上面的测试中,看似已经将 p1
对应的教授变成了 Bob
;但是在数据库中之前 t1
老师所对应的教授信息还存在,此时的赋值操作并不会覆盖掉教授他之前的教授数据,只是重新创建了一条。
正确的做法应该是将某一条数据的一对一关系通过 delete
关系先删除之后再重新赋予
Original: https://blog.csdn.net/HeroicLee/article/details/121382601
Author: 李恩泽的技术博客
Title: Django模型操作之增删改查大全
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/736272/
转载文章受原作者版权保护。转载请注明原作者出处!