Django ORM总结

源码:https://blog.csdn.net/feifeiyechuan/article/details/84940951

目录

一、DjangoORM的配置及创建

1、ORM简介

2、配置文件

3、创建数据模型

4、生成表结构

二、Django ORM增删改查

1、数据的添加

2、数据的修改

3、数据的删除

4、数据的查询(重点)

三、ORM字段介绍

1、字段类型

2、字段参数

四、Django ORM模型一对一、一对多、多对多的操作详解



一、DjangoORM的配置及创建

1、ORM简介

ORM:(object relational mapping)关系对象映射。定义一个类自动生成数据库的表结构。

创建数据库的时候,一般有以下几种常用数据类型:数字、字符串以及时间。

ORM分为两种:

  • DB First 数据库里先创建数据库表结构,根据表结构生成类,根据类操作数据库
  • Code First 先写代码,执行代码创建数据库表结构

主流的orm都是code first。django 的orm也是code first,所以学的时候,本质就分为两块:

  • 根据类自动创建数据库表
  • 根据类对数据库表中的数据进行各种操作

2、配置文件

  • 配置显示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'
        },
    }
}
  • 配置数据库mysql

项目settings.py文件中:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',      #连接数据库种类
        'NAME': 'test02_1209',                     #数据库名,****记得提前创建该数据库****
        'USER': 'root',                            #用户名
        'PASSWORD': 'root',                        #密码
        'HOST': '127.0.0.1',                       #登陆主机
        'PORT': '3306',                            #登陆端口
    }
}

同时在项目__init__.py文件中:

原因是在Django中操作数据库是通过名字MySQLdb来识别的,但是python3中用的是pymysql,保证了Django的正确识别。

import pymysql
pymysql.install_as_MySQLdb()
  • 注册app

项目settings.py文件中:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 'usermange.apps.UsermangeConfig',     #pycharm自动生成,与下一行一样的作用
    'usermange',                            #添加app,和上一行一样的意思
]

3、创建数据模型

在usermange应用下的models.py文件中:

from django.db import models

# Create your models here.
class UserInfo(models.Model):
    id = models.AutoField(primary_key=True)
    uname = models.CharField(max_length=20)
    uage = models.IntegerField()
    ucdate = models.DateField(auto_now_add=True)
    umdate = models.DateField(auto_now = True)

4、生成表结构

在命令行中执行命令生成表结构:

python manage.py  makemigrations    #生成migrations临时文件
python manage.py  migrate           #根据生成的migrations直接生成数据库表结构

#后续每次如果更改了表结构,按顺序执行这两条命令即可

二、Django ORM增删改查

1、数据的添加

#方法一:
UserInfo(uname='gaofei',uage=11).save()

# 方法二
userobj = UserInfo()
userobj.uname = 'zhang3'
userobj.uage = 22
userobj.save()

# 方法三
UserInfo.objects.create(uname='li4',uage=23)

#方法四
userobj1 = UserInfo.objects.get_or_create(uname='wang5', uage=24,default={'uname':'z6','uage':22})
print(userobj1)
#(<UserInfo: UserInfo object (4)>, True)   
#如果通过前面的条件没有找到数据,那么新建一条记录,记录的字段赋值为default中的参数,返回(新建的对象,True)
# (< UserInfo: UserInfo object (4) >, False)    #如果通过前面的条件查找到了一条数据,返回(该对象,False)

# 方法五:推荐使用
dicts = {'uname':'gaofeifeifei','uage':'22'}
UserInfo(**dicts).save()

2、数据的修改

#===数据的修改
#批量更新:谨慎使用,如果数据量小最好用单个跟新
UserInfo.objects.filter(id=7).update(uname='gaofeifei')

# 单个更新,自动时间的跟新只支持单个跟新不支持批量跟新
userobj2 = UserInfo.objects.filter(id=7)[0]
userobj2.uname = 'gaofei'
userobj2.save()

#跟新或者创建
userobj3 = UserInfo.objects.update_or_create(uname='li4',uage=23,default='uname':'z6','uage':33})        
#和get_or__create类似
#如果通过前面的uname,uage找到一条记录,按照default中的字段值进行修改,返回(跟新后的对象,False)
#如果通过前面的uname,uage找不到记录,新建一条记录按照default中的字段值进行赋值,返回(新建的对象,True)

3、数据的删除

#批量删除,同样谨慎使用,别一失足成千古恨
UserInfo.objects.filter(uname='gaofeifei').delete()  #删除满足条件的
UserInfo.objects.all().delete()     #删除所有
#单个删除
userobj5 = UserInfo.objects.get(id = 8)
userobj5.delete()   #虽然是两句话,但是执行的是一个sql语句
# 执行的sql语句为:
# DELETE FROM `usermange_userinfo` WHERE `usermange_userinfo`.`id` IN(8)

4、数据的查询(重点)

(1)查询所有数据的方法 

# 1、---查询所有数据的方法
datas1 =  UserInfo.objects.all()      #返回类型QquerySet,内部是所有对象的集合
datas2 = UserInfo.objects.values()      #返回列表类型,是对象对应字典为元素的列表
print(type(datas1),'==>',datas1)
print(type(datas2),'==>',datas2)

# ----注意,对于返回值类型为QuerySet类型的数据,可以使用切片进行截取数据
print(datas1[2])   #获取下表索引为2的数据对象 使用了sql
print(datas1[1:3])   #获取下表1到3(取左不取右)的对象集合,类型为QuerySets   使用了python内部的排序
print(datas1[1:3:-1])    #倒序输出对象列表   使用了python的倒叙排列

(2)按照条件查询数据 

  • 返回新QuerySets的API 

      方法名                    解释

  1. filter()            过滤查询对象。
  2. exclude()            排除满足条件的对象
  3. annotate()            使用聚合函数
  4. order_by()            对查询集进行排序
  5. reverse()            反向排序
  6. distinct()            对查询集去重
  7. values()            返回包含对象具体值的字典的QuerySet
  8. values_list()        与values()类似,只是返回的是元组而不是字典。
  9. dates()                根据日期获取查询集
  10. datetimes()            根据时间获取查询集
  11. none()                创建空的查询集
  12. all()                获取所有的对象
  13. union()                并集
  14. intersection()        交集
  15. difference()        差集
  16. select_related()    附带查询关联对象
  17. prefetch_related()    预先查询
  18. extra()                附加SQL查询
  19. defer()                不加载指定字段
  20. only()                只加载指定的字段
  21. using()                选择数据库
  22. select_for_update()    锁住选择的对象,直到事务结束。
  23. raw()                接收一个原始的SQL查询
  •  具体使用

#--filter
datas3 = UserInfo.objects.filter(uname='li4', uage=23)  #获取同时满足参数的数据QuerySet集合
print(type(datas3),'==>',datas3)

#--get
datas4 = UserInfo.objects.get(id = 6)   #获取同时满足参数的对象,如果查询结果为空或者有多条数据,报错
dataobj1 = UserInfo.objects.first()     #返回第一个对象
dataobj2 = UserInfo.objects.last()      #返回最后一个对象

#--exclude
datas5 = UserInfo.objects.exclude(uname='li4')   #获取不满足条件的数据QuerySet集合\

#reverse()
datas6 = UserInfo.objects.all().reverse()   #获取反转后的结果集,类型为QuerySet,可以进行多次的reverse()

#distinct()
# datas7 = UserInfo.objects.values('uname','id').distinct()   #根据uname,id进行去重,返回去重后的QuerySet集合,内部为字典为元素的列表
# print(datas7)
#
# #order_by()
datas8 = UserInfo.objects.all().order_by('id') #根据id进行升序排序      返回结果为QuerySet,对象集合
datas8 = UserInfo.objects.all().order_by('-id') #根据id进行降序配许

#count()
data9 = UserInfo.objects.all().count()      # 统计结果数量 #通过sql语句
data9 = UserInfo.objects.values().count()
data9 = UserInfo.objects.count()

#exists()
datas10 = UserInfo.objects.all().exists()   #是否查询到数据,这个还是通过sql查询所有数据,如果返回有值为True,否则为False
datas10 = UserInfo.objects.values().exists()
datas10 = UserInfo.objects.filter(id=6).exists()

#values_lists()
datas11 = UserInfo.objects.values_list()    #返回的结果集(QuerySet内部为结果元组为元素组成的列表)
  •  链式查找
#链式查找
UserInfo.objects.filter(uname__contains='li')   #模糊查询
UserInfo.objects.filter(uname__icontains='li')  #忽略大小写模糊查询
UserInfo.objects.filter(uname__regex= 'li4$')   #正则匹配
UserInfo.objects.filter(uname__iregex= 'li4$')  #忽略大小写正则匹配
UserInfo.objects.filter(uname__exact='li4')     #全匹配
UserInfo.objects.filter(uname__iexact='li4')    #忽略大小写全匹配
UserInfo.objects.filter(uname__startswith='l')  #以。。。开头
UserInfo.objects.filter(uname__istartswith='l') #忽略大小写,以。。。开头
UserInfo.objects.filter(uname__endswith='l')    #以。。。结束
UserInfo.objects.filter(uname__iendswith='l')   #忽略大小写,以。。。结束
UserInfo.objects.filter(uname__in=('i','li4'))  #值是否在这个集合中,参数可以是列表,元组,集合
UserInfo.objects.filter(uage__lt=5)             # 小于-------------------以下适用数字类型
UserInfo.objects.filter(uage__lte=5)            #小于等于
UserInfo.objects.filter(uage__gt=5)             #大于
UserInfo.objects.filter(uage__gte=5)            #大于等于
UserInfo.objects.filter(uage__range=(11,12))   #在11-12范围内,包含11和12
UserInfo.objects.filter(ucdate__year=2018)      #年份是否为2018-----------以下适用日期类型
UserInfo.objects.filter(ucdate__month=12)       #月份为12
UserInfo.objects.filter(ucdate__day=10)         #日期为10
print(UserInfo.objects.filter(ucdate__week_day= 1) )   #星期一    #the day of week from 1 (Sunday) to 7 (Saturday)
print()

UserInfo.objects.filter(ucdate__hour=12)        #12点
UserInfo.objects.filter(ucdate__minute=20)      #20分
UserInfo.objects.filter(ucdate__second=10)      #10秒

三、ORM字段介绍

1、字段类型

1、models.AutoField  自增列 = int(11)
  如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。
2、models.CharField  字符串字段
  必须 max_length 参数
3、models.BooleanField  布尔类型=tinyint(1)
  不能为空,Blank=True
4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar
  继承CharField,所以必须 max_lenght 参数
5、models.DateField  日期类型 date
  对于参数,auto_now = True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。
6、models.DateTimeField  日期类型 datetime
  同DateField的参数
7、models.Decimal  十进制小数类型 = decimal
  必须指定整数位max_digits和小数位decimal_places
8、models.EmailField  字符串类型(正则表达式邮箱) =varchar
  对字符串进行正则表达式
9、models.FloatField  浮点类型 = double
10、models.IntegerField  整形
11、models.BigIntegerField  长整形
  integer_field_ranges = {
    'SmallIntegerField': (-32768, 32767),
    'IntegerField': (-2147483648, 2147483647),
    'BigIntegerField': (-9223372036854775808, 9223372036854775807),
    'PositiveSmallIntegerField': (0, 32767),
    'PositiveIntegerField': (0, 2147483647),
  }
12、models.IPAddressField  字符串类型(ip4正则表达式)(已弃用,用13、)
13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)
  参数protocol可以是:both、ipv4、ipv6
  验证时,会根据设置报错
14、models.NullBooleanField  允许为空的布尔类型
15、models.PositiveIntegerFiel  正Integer
16、models.PositiveSmallIntegerField  正smallInteger
17、models.SlugField  减号、下划线、字母、数字
18、models.SmallIntegerField  数字
  数据库中的字段有:tinyint、smallint、int、bigint
19、models.TextField  字符串=longtext
20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]
21、models.URLField  字符串,地址正则表达式
22、models.BinaryField  二进制
23、models.ImageField   图片
24、models.FilePathField 文件
25、distance_bigger_better_choice = (    # 枚举
        (1, '是'),
        (0, '不是')
    )
distance_bigger_better = models.IntegerField(verbose_name="相似距离是否越大越像", choices=distance_bigger_better_choice)

2、字段参数

null                # 是否可以为空
default             # 默认值
primary_key         # 主键
db_column           # 列名
db_index            # 索引(db_index=True)
unique              # 唯一索引(unique=True)
unique_for_date     # 只对日期索引
unique_for_month    # 只对月份索引
unique_for_year     # 只对年做索引
auto_now            # 创建时,自动生成时间
auto_now_add        # 更新时,自动更新为当前时间

注意:更新时间的话,需要使用单个更新,不能使用批量更新,因为时间的更新是python增的操作,不是sql的操作。单个更新会把所有的数据进行重新提交。

四、Django ORM模型一对一、一对多、多对多的操作详解

五、更新model和库

发布了84 篇原创文章 · 获赞 149 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/feifeiyechuan/article/details/84934078
今日推荐