django之模型层(django模块详解)

网友投稿 1000 2022-09-10

django之模型层(django模块详解)

django之模型层(django模块详解)

配置测试脚本

第一种方法:

直接在某一个应用下的test文件中书写(前四行代码去manage.py中拷贝):

import os

if __name__ == "__main__":

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

import django

django.setup()

第二种方法:

直接新建一个任意名称的py文件 在里面写上上面的配置

ORM单表操作

先前操作

# 模型类

class Books(models.Model):

title = models.CharField(max_length=32)

price = models.DecimalField(max_digits=8, decimal_places=2)

publish_date = models.DateField()

创建数据

# 方式1:create方法

models.Books.objects.create(title='三国演义', price=345.66, publish_date='2019-11-27')

# 方式2:利用对象的绑定方法

book_obj = models.Books(title='红楼梦', price=235.66, publish_date='2018-09-12')

book_obj.save()

修改数据

# 方式1:利用queryset方法

res = book_obj = models.Books.objects.filter(pk=1).update(price=320.23)

print(res) # ]>

# 方式2:利用对象 (不推荐使用) 利用对象修改 内部其实是从头到尾将数据的所有字段都重新写一遍

book_obj = models.Books.objects.get(pk=2)

book_obj.price = 150.33

book_obj.save()

注:

pk会自动查找当前表的主键字段

filter查询出来的结果是一个QuerySet对象

QuerySet对象特点

只要是QuerySet对象就可以无限制的调用QuerySet的方法

book_obj = models.Books.objects.filter(pk=1).filter().filter()

# 可以无限制 的删选

只要是QuerySet对象就可以用句点符 点query查看当前内部对应的sql语句

book_obj = models.Books.objects.filter(pk=1)

print(book_obj.query)

get和filter区别

filter获取到的是一个queryset对象,类似于一个列表

get获取到的直接就是数据对象本身

当条件不存在时,filter不报错直接返回一个空,get直接报错

删除数据

# 方式1:

models.Books.objects.filter(pk=7).delete()

# 方式2:

book_obj = models.Books.objects.get(pk=6)

book_obj.delete()

必知必会13条操作

如果想要在终端查看 orm对应的sql语句,可以在settings.py中加配置

LOGGING = {

'version': 1,

'disable_existing_loggers': False,

'handlers': {

'console':{

'level':'DEBUG',

'class':'logging.StreamHandler',

},

},

'loggers': {

'django.db.backends': {

'handlers': ['console'],

'propagate': True,

'level':'DEBUG',

},

}

}

1. all() 查询所有

返回的是queryset对象

res = models.Books.objects.all()

print(res)

注意:orm语句的查询默认是惰性查询,只有当你真正使用数据的时候才会执行orm语句

2. filter() 筛选

相当于原生SQL语句的where

res = models.Books.objects.filter(pk=3, title='人') # 可以传多个参数,and关系

print(res)

3. get()

筛选,获取的是数据对象本身,条件不存在时报错, 而且查询条件只能是一个

res = models.Books.object.get(pk=2)

print(res)

4. first()

取queryset中第一个数据对象

res = models.Books.objects.filter(title='西游记').first()

print(res.price)

5. last()

取queryset中最后一个数据对象

res = models.Books.objects.filter(title='西游记').last()

print(res)

6. count()

统计数据的个数

num = models.Books.objects.count()

print(num)

7. values()

获取对象中指定字段的值,可以传多个参数,返回的是 queryset对象 列表套字典

res = models.Books.objects.values('title','price')

print(res)

8. values_list()

获取对象中指定字段的值,可以传多个参数,返回的是 queryset对象 列表套元组

res = models.Books.objects.values_list('title','price')

print(res)

9. order_by()

按照指定的字段排序, 默认是升序

降序只要在字段前面加负号(-)

res = models.Books.objects.order_by('price')

res = models.Books.objects.all().order_by('price') # 两者等价,默认是升序

res = models.Books.objects.order_by('-rice')

10. reverse()

颠倒顺序的前提是 颠倒的对象必须要有顺序(提前排序之后才能颠倒顺序)

所以必须和order_by联用

res = models.Books.objects.order_by('price')

res1 = models.Books.objects.all().order_by('price').reverse()

print(res1)

11. exclude()

排除

res = models.Books.objects.all().exclude(title='人间失格')

print(res)

12. exists()

判断查询结果是否有值,返回结果是一个布尔值

res = models.Books.objects.filter(pk=12).exists()

print(res)

13. distinct()

对查询结果去重,但是必须要有完全相同的数据,才能去重

注意:主键id不一样,会忽略

res = models.Books.objects.values('title','price').distinct()

print(res)

双下划线查询

__gt 大于

__lt 小于

__gte 大于等于

__lte 小于等于

__range 范围查询 顾头顾尾

__in 在里面

__year

__month

# 查询价格大于200的书籍

res = models.Books.objects.filter(price__gt=200)

print(res)

# 查询价格小于300 的书籍

res = models.Books.objects.filter(price__lt=200)

print(res)

# 查询价格大于等于200

res = models.Books.objects.filter(price__gte=200)

print(res)

# 查询价格小于等于200

res = models.Books.objects.filter(price__lte=200)

print(res)

# 查询价格在200~300之间的书籍

res = models.Books.objects.filter(price__range(200, 300)) # 顾头顾尾

print(res)

# 查询价格是200 或 300 的书籍

res = models.Books.objects.filter(price__in[200, 300])

print(res)

# 查询出版日期为2019年的书籍

res = models.Books.objects.filter(publish_date__year=2019)

print(res)

# 查询出版日期是11月份的书籍

res = models.Books.objects.filter(publish_date__month=11)

print(res)

__startswitch 以....开头

__endswith 以...结尾

__contains 包含 如果查询字母,默认区分大小写

__icontains 加 i 忽略大小写

# 查询书籍是以“人”开头的书

res = models.Books.objects.filter(title__startswith='人')

print(res)

# 查询书籍是以“梦”结尾的书

res = models.Books.objects.filter(title__endswith='梦')

print(res)

# 查询书籍名称中包含“的”字的书籍

res = models.Books.objects.filter(title__contains='的')

print(res)

# 查询书籍名称中包含字母p的书籍

res = models.Books.objects.filter(title__contains='p') # 默认区分大小写

res = models.Books.objects.filter(title__icontains='p') # 加i不区分大小

一对多字段外键增删改查

准备工作

class Book(models.Model):

title = models.CharField(max_length=32)

price = models.DecimalField(max_digits=8, decimal_places=2)

publish_date = models.DateField(auto_now_add=True)

publish = models.ForeignKey(to='Publish')

authors = models.ManyToManyField(to='Author')

class Publish(models.Model):

name = models.CharField(max_length=32)

addr = models.CharField(max_length=64)

class Author(models.Model):

name = models.CharField(max_length=32)

email = models.EmailField()

author_detail = models.OneToOneField(to='AuthorDetail')

class AuthorDetail(models.Model):

phone = models.BigIntegerField()

addr = models.CharField(max_length=64)

花式操作

增:

# 方法1 :直接传表里面的实际字段

models.Book.objects.create(title='人间失格', price=123.56, publish_id=1)

# 方法2 :传虚拟字段 跟数据对象即可

publish_obj = models.Publish.objects.filter(pk=2).first()

models.Book.objects.create(title='水浒传', price=223.45, publish=publish_obj)

改:

# 方法1: 直接传实际字段

models.Book.objects.filter(pk=1).update(publish_id=2)

# 方法2:传数据对象

publish_obj = models.Publish.objects.filter(pk=1).first()

models.Book.objects.filter(pk=1).update(publish=publish_obj)

删:

# 默认就是级联删除 级联更新

models.Publish.objects.filter(pk=1).delete()

多对多外键字段的增删改查

增:add

book_obj = models.Book.objects.filter(pk=1).first()

book_obj.authors.add(1) # book_obj.authors 就已经进入第三张表了

# 同样支持传数据对象

book_obj = models.Book.objects.filter(pk=2).first()

author_obj = models.Author.objects.filter(pk=2).first()

book_obj.authors.add(author_obj)

# 数据对象也支持传多个

book_obj = models.Book.objects.filter(pk=2).first()

author_obj1 = models.Author.objects.filter(pk=1).first()

author_obj2 = models.Author.objects.filter(pk=2).first()

book_obj.authors.add(author_obj1, author_obj2)

add方法 能够想第三张关系表添加数据

支持传数字

也支持传对象,并且两者都可以是多个

改:set

# 方法1:传字段

book_obj = models.Book.objects.filter(pk=2).first()

book_obj.authors.set([1, 3])

book_obj.authors.set([1,]) # set里面要传可迭代对象

# 方法2:传数据对象

author_obj1 = models.Author.objects.filter(pk=1).first()

author_obj2 = models.Author.objects.filter(pk=2).first()

book_obj.authors.set((author_obj1,author_obj2))

set方法 能修改多对多关系表中的数据

可以传数字,也可以传对象,都支持传多个

set里面传的是可迭代对象

删:remove

# 方法1:传字段

book_obj = models.Book.objects.filter(pk=2).first()

book_obj.authors.remove(1)

book_obj.authors.remove(1, 2) # 支持多个

# 方法2:传数据对象

book_obj = models.Book.objects.filter(pk=1).first()

author_obj = models.Author.objects.filter(pk=1).first()

book_obj.authors.remove(author_obj)

remove方法 能删除多对多关系表中的数据

可以传数字,也可以传对象,

都支持传多个, 不需要传迭代对象

清空:clear

book_obj = models.Book.objects.filter(pk=2).first()

book_obj.authors.clear()

clear清空数据,括号里面不需要传参数

跨表查询

正反向查询

正向查询 关系字段在谁那,由有关系字段的表查,就是正向查询

反向查询 关系字段不在那

正向查询按字段,反向查询按表名小写 + _set

基于对象的跨表查询(子查询)

# 1.查询书籍主键为2的出版社名称

book_obj = models.Book.objects.filter(pk=2).first()

print(book_obj.publish.name)

book_obj = models.Book.objects.filter(pk=1).first()

# print(book_obj.authors) # app01.Author.None

print(book_obj.authors.all()) # 当正向查询点击外键字段数据有多个的情况下 需要.all()

author_obj = models.Author.objects.filter(name='式微').first()

print(author_obj.author_detail.phone)

# 4.查询出版社是东方出版社出版过的书籍

publish_obj = models.Publish.objects.filter(name='东方出版社').first()

print(publish_obj.book_set.all())

author_detail_obj = models.AuthorDetail.objects.filter(phone=120).first()

print(author_detail_obj.author.name)

author_obj = models.Author.objects.filter(name='无名').first()

print(author_obj.book_set.all())

总结:

正向查询,点击外键字段数据有多个的情况下 需要.all()

反向查询,一对多和多对多需要表名 + _set,一对一不需要加_set

基于双下划线的跨表查询(联表查询)

# 1.查询书籍pk为2的出版社名称

res = models.Book.objects.filter(pk=2).values('publish__name')

print(res)

res = models.Publish.objects.filter(book__pk=2).values('name')

res = models.Book.objects.filter(pk=2).values('authors__name', 'authors__email')

print(res)

res = models.Author.objects.filter(book__pk=2).values('name', 'email')

res = models.Author.objects.filter(name='邶风').values('author_detail__addr')

print(res)

res = models.AuthorDetail.objects.filter(author__name='邶风').values('addr')

# 4.查询出版社是东方出版社出版过的书的名字

res = models.Publish.objects.filter(name='东方出版社').values('book__title')

print(res)

res = models.Book.objects.filter(publish__name='东方出版社').values('title')

res = models.Book.objects.filter(pk=2).values('authors__author_detail__phone')

print(res)

res = models.Author.objects.filter(book__pk=2).values('author_detail__phone')

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:二、JSP常用小知识之http 403错误
下一篇:批量获取服务器服务编码(序列号)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~