ORM-Object Relational Mapping

ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

1.ORM的优势

ORM解决的主要问题是对象和关系的映射。它通常将一个类和一张表一一对应,类的每个实例对应表中的一条记录,类的每个属性对应表中的每个字段。

ORM提供了对数据库的映射,不用直接编写SQL代码,只需操作对象就能对数据库操作数据。

让软件开发人员专注于业务逻辑的处理,提高了开发效率。

2.ORM的劣势

ORM的缺点是会在一定程度上牺牲程序的执行效率。

ORM的操作是有限的,也就是ORM定义好的操作是可以完成的,一些复杂的查询操作是完成不了。

ORM用多了SQL语句就不会写了,关系数据库相关技能退化…

3.ORM总结:

ORM只是一种工具,工具确实能解决一些重复,简单的劳动。这是不可否认的。

但我们不能指望某个工具能一劳永逸地解决所有问题,一些特殊问题还是需要特殊处理的。

但是在整个软件开发过程中需要特殊处理的情况应该都是很少的,否则所谓的工具也就失去了它存在的意义。

1.字段

1.1常用字段

AutoField

自增的整形字段,必填参数primary_key=True,则成为数据库的主键。无该字段时,django自动创建。

一个model不能有两个AutoField字段。

IntegerField

一个整数类型。数值的范围是 -2147483648 ~ 2147483647。

CharField

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

DateField

日期类型,日期格式为YYYY-MM-DD,相当于Python中的datetime.date的实例。

参数:

  • auto_now:每次修改时修改为当前日期时间。
  • auto_now_add:新创建对象时自动添加当前日期时间。

auto_now和auto_now_add和default参数是互斥的,不能同时设置。

DatetimeField

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

1.2自定义字段
1.3字段参数
null                数据库中字段是否可以为空
db_column           数据库中字段的列名
default             数据库中字段的默认值
primary_key         数据库中字段是否为主键
db_index            数据库中字段是否可以建立索引
unique              数据库中字段是否可以建立唯一索引
unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引
unique_for_month    数据库中字段【月】部分是否可以建立唯一索引
unique_for_year     数据库中字段【年】部分是否可以建立唯一索引
 
verbose_name        Admin中显示的字段名称
blank               Admin中是否允许用户输入为空
editable            Admin中是否可以编辑
help_text           Admin中该字段的提示信息
choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
                   如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
 
error_messages      自定义错误信息(字典类型),从而定制想要显示的错误信息;
                字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                        如:{'null': "不能为空.", 'invalid': '格式错误'}
 
    validators          自定义错误验证(列表类型),从而定制想要的验证规则
                        from django.core.validators import RegexValidator
                        from django.core.validators import EmailValidator,URLValidator,DecimalValidator,\
                        MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                        如:
                            test = models.CharField(
                                max_length=32,
                                error_messages={
                                    'c1': '优先错信息1',
                                    'c2': '优先错信息2',
                                    'c3': '优先错信息3',
                                },
                                validators=[
                                    RegexValidator(regex='root_\d+', message='错误了', code='c1'),
                                    RegexValidator(regex='root_112233\d+', message='又错误了', code='c2'),
                                    EmailValidator(message='又错误了', code='c3'), ]
                            )
 

2.查询的方法(13个)

序号方法用法
1all()查询所有结果
2get(**kwargs)返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
3filter(**kwargs)它包含了与所给筛选条件相匹配的对象
4exclude(**kwargs)它包含了与所给筛选条件不匹配的对象
5values(*field)返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列model的实例化对象,而是一个可迭代的字典序列. 括号内指定字段,默认获取所有字段的名和值,如果指定字段则获取指定字段的名和值,并按照指定的顺序显示.
6values_list(*field)它与values()非常相似,它返回的是一个元组序列,(values返回的是一个字典序列)只有values中的值,没有名,也可以指定字段,按照顺序显示.
7order_by(*field)对查询结果排序,可以写多个字段 默认升序,加负号是降序
8reverse()对查询结果反向排序,请注意reverse()通常只能在具有已定义顺序的QuerySet上调用(在model类的Meta中指定ordering或调用order_by()方法)。
9distinct()从返回结果中剔除重复纪录(如果你查询跨越多个表,可能在计算QuerySet时得到重复的结果。此时可以使用distinct(),注意只有在PostgreSQL中支持按字段去重。)
10count()返回数据库中匹配查询(QuerySet)的对象数量
11first()返回第一条记录,可以取代get,没有的时候就是None
12last()返回最后一条记录
13exists()如果QuerySet包含数据,就返回True,否则返回False,可以用在filter后面

分类:

返回QuerySet对象的方法有
  • all()

  • filter()

  • exclude()
  • order_by()

  • reverse()

  • distinct()

特殊的QuerySet
  • values() 返回一个可迭代的字典序列
  • values_list() 返回一个可迭代的元祖序列
返回具体对象的
  • get()
  • first()
  • last()
返回布尔值的方法有:
  • exists()
返回数字的方法有
  • count()

3.单表查询-双下划线

models.Tb1.objects.filter(id__lt=10, id__gt=1)   # 获取id大于1 且 小于10的值
models.Tb1.objects.filter(id__lte=10, id__gte=1) #大于等于1,小于等于10的
models.Tb1.objects.filter(id__exact=1) #等于1

models.Tb1.objects.filter(id__in=[11, 22, 33])   # 获取id等于11、22、33的数据
models.Tb1.objects.exclude(id__in=[11, 22, 33])  # not in
 						__isnull=True  
models.Tb1.objects.filter(name__contains="ven")  # 获取name字段包含"ven"的,like
models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
 
models.Tb1.objects.filter(id__range=[1, 3])      # id范围是1到3的,等价于SQL的bettwen and  闭合[1,3]
类似的还有:startswith,istartswith(忽略大小写的), endswith, iendswith 

date字段还可以:
models.Class.objects.filter(first_day__year=2017)

4.ForeignKey操作

正向查询

book_obj.publisher 关联的对象

反向查询

默认用obj.表名_set管理对象 如果指定了related_name=“books”,则直接用obj.books管理对象

# 查询出出版社出版的所有书籍
# 不指定 related_name='books'
print(pub_obj.book_set,type(pub_obj.book_set))
print(pub_obj.book_set.all())

# 指定related_name='books'
print(pub_obj.books,type(pub_obj.books))
print(pub_obj.books.all())

基于字段的查询

models.Book.objects.filter(publisher__name=“沙河出版社”)跨表

# 基于字段的查询
ret = models.Book.objects.filter(publisher__name='老男孩出版社')

# 不指定related_name
ret = models.Pubisher.objects.filter(book__title='太亮教开车')

# 指定related_name=books
ret = models.Publisher.objects.filter(books__title='太亮教开车')

# 指定related_query_name='book'
ret = models.Publisher.objects.filter(book__title='太亮教开车')
print(ret)

# 外键字段可以为null 才有remove和clear  只能写对象
pub_obj = models.Publisher.objects.get(id=1)
# pub_obj.books.remove(models.Book.objects.get(id=1))
# pub_obj.books.clear()

pub_obj.books.create(title='太亮的产后护理')

5.多对多的操作

# 基于对象的查询
# 正向
author_obj = models.Author.objects.get(id=2)
#
print(author_obj.books,type(author_obj.books))
print(author_obj.books.all())

# 反向
book_obj = models.Book.objects.get(id=1)

# 不指定related_name='authors'
print(book_obj.author_set.all())

# 指定related_name='authors'
print(book_obj.authors.all())


# set 设置多对多关系
author_obj.books.set([])
author_obj.books.set([1,2,3])   # 要关联对象的ID  [ 对象的id,对象的id]
author_obj.books.set(models.Book.objects.all())   # 要关联对象  [ 对象,对象]


# add 添加多对多的关系  不改变原有的关联对象,直接添加
author_obj.books.add(1)  # 要关联对象的ID
author_obj.books.add(models.Book.objects.get(id=2))  # 要关联对象

# remove()  删除多对多的关系
author_obj.books.remove(1)  # 要关联对象的id
author_obj.books.remove(models.Book.objects.get(id=2))  # 要关联对象

# clear()  # 清空当前对象的多对多的关系
author_obj.books.clear()

# create()
author_obj.books.create(title='太亮教抛光',)#在book表中创建一条title='太亮教抛光'的数据,并关联到这个author_obj
book_obj.authors.create(name='alex')#在author中创建一个alex作者,并关联到book_obj

6.聚合

aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。后面不能再跟别的语句

键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。

用到的内置函数:

from django.db.models import Avg, Sum, Max, Min, Count
ret = models.Book.objects.aggregate(max=Max('price'))  # max是别名,结果中的key  得到的是{ }

print(models.Book.objects.aggregate(Avg("price"), Max("price"), Min("price")))
print(models.Book.objects.all().aggregate(Avg("price"), Max("price"), Min("price")))
#两个效果是一样的

7.分组

annotate前没有指定values,默认按照前面的对象分组,

如果指定了values,按照values分组.

# 统计出每个出版社卖的最便宜的书的价格
# 方法一    以出版社的id进行分组
ret=models.Publisher.objects.all().annotate(Min('book__price')).values()
for i in ret:
    print(i)#不加values() 拿到的是对象 加values后拿到的是键值对  all()加不加都可以

# 方法二	values指定以什么字段进行分组,后面的values不能写其他额外的字段
ret=models.Book.objects.values('publisher__name').annotate(min=Min('price')).values('min')
for i in ret:
    print(i)

8.F查询

F的作用 :动态的获取某个字段的值

from django.db.models import F
# 动态地获取字段的值
#筛选kucun>sale的book
ret= models.Book.objects.filter(kucun__gt=F('sale')).values()
#sale=原来的2倍
models.Book.objects.all().update(sale=F('sale')*2)  # update更新指定字段

9.Q查询

Q 对象可以使用~ 操作符取反 ,&与 和| 或 操作符以及使用括号进行分组来编写任意复杂的Q 对象

from django.db.models import Q
ret = models.Book.objects.filter(Q(~Q(id__lt=3) | Q(id__gt=5))&Q(id__lt=4))
print(ret) 

10.事务

一系列操作要同时成功执行,或都不执行,保证原子性操作。同生共死

from app01 import models
from django.db import transaction

try:
    with transaction.atomic():
        models.Publisher.objects.create(name='新华出版社1')
        int('aaa')
        models.Publisher.objects.create(name='新华出版社2')
        models.Publisher.objects.create(name='新华出版社2')
except Exception as e:
        print(e)	

11.在Python脚本中调用Django环境

import os

if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "BMS.settings")
    import django
    django.setup()

    from app01 import models

    books = models.Book.objects.all()
    print(books)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值