django ORM相关

目录:

  1. ORM基础
  2. ORM常用字段和参数
  3. 13个必知ORM操作
  4. ORM关系字段
  5. ORM跨表查询
  6. 基于双下划线的查询

ORM基础

  • 类 >>> 数据库的表

  • 对象 >>> 数据库里面的一条条的表记录

  • 对象点属性 >>> 表记录的某个字段对应的值

在视图中操作orm

1.create()
		modeles.User.objects.create(kwargs)
		create方法会返回当前所创建的数据对象(*****)
	2.对象.save()
		user_obj = models.User()
		user_obj.username = 'jason'
		user_obj.save()
删
	queryset对象.delete()1.update()
		models.User.objects.filter(kwargs).update()
		批量更新
	
	2.对象.save()
		user_obj = models.User(kwargs)
		user_obj.username = 'jason'
		user_obj.save()
		效率较低
查
	1.all()  查所有 不需要传参数
	2.filter(kwargs)  结构是一个queryset对象 你可以把它看成一个列表里面是一个个的数据对象

bulk_create批量插入数据

# 一次性插入多条数据

data = ["".join([str(random.randint(65, 99)) for i in range(4)]) for j in range(100)]
obj_list = [models.A(name=i) for i in data]
models.A.objects.bulk_create(obj_list)

在这里插入图片描述
回到目录



ORM常用字段和参数

官方文档:https://docs.djangoproject.com/zh-hans/2.1/ref/models/fields/#field-types

  • AutoField
    int自增列,必须填入参数 primary_key=True。当model中如果没有自增列,则自动会创建一个列名为id的列。

  • IntegerField
    一个整数类型,范围在 -2147483648 to 2147483647。(一般不用它来存手机号(位数也不够),直接用字符串存,)

  • CharField
    字符类型,必须提供max_length参数, max_length表示字符长度。

    注意: 这里需要知道的是Django中的CharField对应的MySQL数据库中的varchar类型,没有设置对应char类型的字段

  • DateField
    日期字段,日期格式 YYYY-MM-DD,相当于Python中的datetime.date()实例。

  • DateTimeField
    日期时间字段,格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ],相当于Python中的datetime.datetime()实例。

字段参数

  • null
    用于表示某个字段可以为空。

  • unique
    如果设置为unique=True 则该字段在此表中必须是唯一的 。

  • db_index
    如果db_index=True 则代表着为此字段设置索引。

  • default
    为该字段设置默认值。

DateField中的参数

  • auto_now:每次操作该数据的时候 都会自动更新当前时间
  • auto_now_add:数据第一次创建的时候 会将创建时间自动记录下来 后续的改动不会再自动更新该字段

回到目录



13个必知ORM操作

返回QuerySet对象的方法有

all()

filter()

exclude()

order_by()

reverse()

distinct()

特殊的QuerySet

values()       返回一个可迭代的字典序列

values_list() 返回一个可迭代的元祖序列

返回具体对象的

get()

first()

last()

返回布尔值的方法有:

exists()

返回数字的方法有

count()

回到目录



ORM关系字段

ForeignKey字段(一对多)

外键类型在ORM中用来表示外键关联关系,一般把ForeignKey字段设置在 '一对多’中’多’的一方。
ForeignKey可以和其他表做关联关系同时也可以和自身做关联关系。

字段参数

  • to
    设置要关联的表

  • to_field
    设置要关联的表的字段

  • on_delete
    当删除关联表中的数据时,当前表与其关联的行的行为。

  • models.CASCADE

  • 删除关联数据,与之关联也删除

  • db_constraint
    是否在数据库中创建外键约束,默认为True。

示例

class MyModel(models.Model):
    user = models.ForeignKey(
        to="User",
        to_field="id",
        on_delete=models.CASCADE
    )

OneToOneField

常用于拆表
通常一对一字段用来扩展已有字段。(通俗的说就是一个人的所有信息不是放在一张表里面的,简单的信息一张表,隐私的信息另一张表,之间通过一对一外键关联)

字段参数

  • to
    设置要关联的表。

  • to_field
    设置要关联的字段。

  • on_delete
    当删除关联表中的数据时,当前表与其关联的行的行为。(参考外键的例子)

ManyToManyField
适用于两种情况:

  • 外键关系的反向查询
  • 多对多关联关系

models.py

authors = models.ManyToManyField(to='Author')  # 默认关联的就是Author表的主键字段

多对多表关系的三种创建方式

1.全自动

authors = models.ManyToManyField(to='Author')
让django orm自动帮你创建第三张表
好处:不需要自己手动添加
坏处:表字段的扩展性极差   只会帮你建外键字段  其他额外字段一概无法创建

2.纯手动(了解)

class Book(models.Model):
	name = ...
class Author(models.Model):
	name = ...
	
class Book2Author(models.Model):
	book_id = models.ForeignKey(to='Book')
	author_id = models.ForeignKey(to='Author')

3.半自动(推荐)

class Book(models.Model):
	name = ...
	authors = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('book','author'))
class Author(models.Model):
	name = ...
	books = models.ManyToManyField(to='Author',through='Book2Author',through_fields=('author','book'))
class Book2Author(models.Model):
	book = models.ForeignKey(to='Book')
	author = models.ForeignKey(to='Author')
	create_time = ...
	info = ...

回到目录



ORM跨表查询

models.py示例:

class Book(models.Model):
    title = models.CharField(max_length=32)
    price = models.CharField(max_length=32)
    publish_date = models.DateField(auto_now_add=True)
    # 出版社外键
    publish = models.ForeignKey(to='Publish')  # 默认关联的就是Publish表的主键字段
    """
    一对多外键字段 在书写的时候 orm会自动加_id后缀
    所以 你不要加_id了
    """
    # 作者外键
    authors = models.ManyToManyField(to='Author')  # 默认关联的就是Author表的主键字段
    """多对多字段是虚拟字段 不会在表中展示出来
        只是用来告诉django orm自动创建书籍和作者的第三张表
        还可以跨表的查询的提供方便
    """

class Publish(models.Model):
    name = models.CharField(max_length=32)
    email = models.EmailField()
    addr = models.CharField(max_length=32)

class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.CharField(max_length=32)
    # 一对一
    """
     一对一外键字段 在书写的时候 orm会自动加_id后缀
    所以 你不要加_id了
    """
    author_detail = models.OneToOneField(to='AuthorDetail')

class AuthorDetail(models.Model):
    phone = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)

ORM多表操作

# 外键字段的增删改查
# models.Book.objects.create(title='三国演义',price='123.23',publish_id=1)
# publish_obj = models.Publish.objects.filter(pk=2).first()
# models.Book.objects.create(title='西游记',price='122.23',publish=publish_obj)

# models.Book.objects.filter(pk=1).update(publish_id=2)
# publish_obj = models.Publish.objects.filter(pk=1).first()
# models.Book.objects.filter(pk=1).update(publish=publish_obj)


# book_obj = models.Book.objects.filter(pk=1).first()
# # book_obj.authors.add(1)  # 在第三张表中 添加书籍和作者的关系
# # book_obj.authors.add(1,2)  # 在第三张表中 添加书籍和作者的关系
# 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即支持传数字 并且也支持传对象
两者都可以是多个
"""

# 改
# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.set([2,])  # 修改
"""
   set即支持传数字 并且也支持传对象
   两者都可以是多个
   但是需要注意的是 传入的格式必须是可迭代对象
"""

# 删
# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.remove(2)
"""
   remove即支持传数字 并且也支持传对象
   两者都可以是多个
"""

# 清空
# book_obj = models.Book.objects.filter(pk=1).first()
# book_obj.authors.clear()  # 清空当前数据所有的关联信息
"""
clear括号内不需要传任何参数
"""

基于对象的跨表查询

基于子查询

# 正向与反向的概念解释
正向查询按字段
反向查询按表名小写...

# 一对一
# 正向:author---关联字段在author表里--->authordetail		按字段
# 反向:authordetail---关联字段在author表里--->author		按表名小写

# 一对多
# 正向:book---关联字段在book表里--->publish		按字段
# 反向:publish---关联字段在book表里--->book		按表名小写_set.all() 因为一个出版社对应着多个图书

# 多对多
# 正向:book---关联字段在book表里--->author		按字段
# 反向:author---关联字段在book表里--->book		按表名小写_set.all() 因为一个作者对应着多个图书

示例:

"""基于对象的跨表查询相当于子查询"""
# 查询书籍id为1的出版社名称
# book_obj = models.Book.objects.filter(pk=1).first()
# print(book_obj.publish.name)
# 查询出版社是南方出版社出版过的书的名字
# publish_obj = models.Publish.objects.filter(name='南方出版社').first()
# # print(publish_obj.book_set)  # app01.Book.None
# print(publish_obj.book_set.all())

# 查询作者是jason的手机号
# author_obj = models.Author.objects.filter(name='jason').first()
# print(author_obj.author_detail.phone)
# 查询手机号是110的作者姓名
# author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first()
# print(author_detail_obj.author.name)

# 查询书籍id为1 的作者姓名
# book_obj = models.Book.objects.filter(pk=1).first()
# # print(book_obj.authors)  # app01.Author.None
# print(book_obj.authors.all())  # app01.Author.None
# 查询作者id为1的写过的书籍
# author_obj = models.Author.objects.filter(pk=1).first()
# print(author_obj.book_set)  # app01.Book.None
# print(author_obj.book_set.all())

回到目录



基于双下划线的查询

基于连表

# 价格 大于 小于 大于等于 小于等于
filter(price__gt='90')
filter(price__lt='90')
filter(price_gte='90')
filter(price_lte='90')

# 存在与某几个条件中
filter(price__in=['11','22','33'])
# 在某个范围内
filter(price__range=[50,90])

# 模糊查询
filter(title__contains='西')
filter(title__icontains='P')

# 以什么开头 以什么结尾

# 按年查询
filter(create_time__year='2017')

# 一对一
-连表查询
		-一对一双下划线查询
			-正向:按字段,跨表可以在filter,也可以在values中
			-反向:按表名小写,跨表可以在filter,也可以在values中
# 查询jason作者的手机号   正向查询  跨表的话,按字段
ret=Author.objects.filter(name='jason').values('authordetail__phone')
# 以authordetail作为基表 反向查询,按表名小写  跨表的话,用表名小写
ret=AuthorDetail.objects.filter(author__name='jason').values('phone')

# 查询jason这个作者的性别和手机号
# 正向
ret=Author.objects.filter(name='jason').values('sex','authordetail__phone')

# 查询手机号是13888888的作者性别
ret=Author.objects.filter(authordetail__phone='13888888').values('sex')
ret=AuthorDetail.objects.filter(phone='13888888').values('author__sex')
    
"""
总结 其实你在查询的时候先把orm查询语句写出来,再看用到的条件是否在当前表内,在就直接获取,不在就按照正向按字段反向按表名来查即可
比如:
	1.查询出版社为北方出版社的所有图书的名字和价格
	res1 = Publish.objects.filter(name='').values('book__name','book__price')
	res2 = Book.objects.filter(publish__name='').values('name','price')
	2.查询北方出版社出版的价格大于19的书
	res1 = Publish.objects.filter(name='',book__price__gt=19).values('book__name','book__price)
"""

回到目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值