Django学习笔记(3)orm模型操作

时间:2020-07-15
本文章向大家介绍Django学习笔记(3)orm模型操作,主要包括Django学习笔记(3)orm模型操作使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

orm概述
什么是ORM
1.Python、PHP、Java是一种开发语言,而MySQL、SQL Server则采用数据库语言,不同语言之间如何实现互操作?
2.SQL语言包括包括数据定义语言DDL、数据控制语言DCL、数据查询语言DQL、数据操作语言DML等,例如INSERT、DELETE、SELECT、UPDATE操作。
3.作为开发人员,应该把精力放在核心业务代码的编写上面,而不应该花太多精力跟数据库语言打交道。
4.ORM(Object-Relational Mapping,对象关系映射)技术可以看做是开发者和数据库之间的桥梁,用于实现数据库和编程语言之间的映射,本质上来看,ORM就是将SQL操作和编程语言操作做了一个翻译。
5.通过ORM技术来操作数据库,使得开发者无需接触SQL语句,而直接操作对象的属性和方法,大大提高了开发效率。

orm的功能
1.映射技术:数据类型映射、类映射、关系映射。例如,每一张数据库表对应开发语言的类,每一个数据字段对应类中的属性。
2.CRUD操作:CRUD即增删查改操作,在SQL语句中通过Insert、Select、Update、Delete来实现,在ORM库中则需要
3.通过对应的函数来实现,例如Django ORM通过get、filter、save、delete函数进行操作。
4.缓存优化:(惰性操作)从数据库查询到的数据以类对象的形式保存在内存,用于随时提取;真正需要查询结果时才执行数据库的select操作,而不是在ORM查询命令执行时查询数据库。

Models介绍
1.通常情况,一个Models对应数据库的一张表
2.Django中Models以类的形式表现
3.它包含了一些基本字段以及数据的一些行为
4.我们只需要在类里面进行操作,就可以操作数据库,表,不需要直接使用SQL语句
5.我们通过创建类来创建数据表,所以对数据库的操作,都是对类与对类的对象进行操作,而不使用sql语句
6.ORM对象关系映射,实现了对象和数据库的映射,隐藏了数据访问的细节,不需要编写SQL语句

models的属性与字段(field)

常用字段类型

AutoField():一个IntegerField,根据可用ID自动递增。如果没指定主键,就创建它自动设置为主键。

IntegerField():一个整数;

FloatField:浮点型

CharField(max_length = None):字符串字段False

DateField(auto_now=False, auto_now_add=False):日期;参数auto_now:每次保存对象时,自动设置该字段为当前时间。用于"最后一次修改"的时间戳. 注意,它总是使用当前日期, 默认为False。参数auto_now_add:当对象第一次被创建时自动设置当前时间。用于创建时间的时间戳. 它总是使用当前日期,默认为False;参数auto_now  auto_now_add default是互相排斥的,组合会发生错误

TImeFiled():时间,参数同DateField

TextField():一个很长的的文本字段,不超过4000字符

BooleanField():布尔字段,True或False;

NullBooleanField():值为Null,True,False;

DecimalField():十进制浮点数,参数max_digits表示总数,参数decimal_places表示小数点数

FileField():上传文件字段

ImageField():用于上传图片并验证图片合法性,需定义upload_to参数,使用本字段需安装pip install pillow图片库;设置upload_to 到某个目录下,需要在settings.py中配置多媒体文件路径: MEDIA_ROOT = os.path.join(BASE_DIR,'static'); models.ImageField(upload_to="article_img" )表示会将从static目录下的article_img文件夹上传图片

OneToOneField(to, on_delete, parent_link = False):一对一

ForeignKey(to, on_delete):一对多

ManyToManyField(to):多对多

字段参数

null:如果设置为True,当该字段为空时,Django会将数据库中该字段设置为NULL。默认为False 。

blank:如果设置为True,该字段允许为空。默认为False。

default:该字段的默认值。可以是一个值或者是个可调用的对象,如果是个可调用对象,每次实例化模型时都会调用该对象。

primary_key:如果设置为 True ,将该字段设置为该模型的主键。

unique:如果设置为 True,这个字段的值必须在整个表中保持唯一。

verbose_name:任何字段类型都接收一个可选的位置参数,如果未指定Django会自动使用字段的属性名作为该参数值,并且把下划线转换为空格。

max_length:设置默认长度,一般在CharField、TextField、EmailField等文本字段设置

choices:设置该字段的可选值,本字段的值是一个二维元素的元祖;元素的第1个值为实际存储的值,第2个值为HTML页面显示的值

upload_to:设置上传路径,ImageField和FileField字段需要设置此参数,如果路径不存在,会自动创建

Meta类属性

verbose_name:设置对象名称(例如usecms),若没有设置,则默认为该类名的小写分词形式,例如类名为CamelCase会被转换为camel case;
verbose_name_plural:设置对象名称复数(例如usercms),一般设置跟verbose_name一样,verbose_name_plural=verbose_name否则会默认加s;
db_table:设置映射的数据表名,默认为“应用名_模型名”,即用该模型所在app的名称加本模型类的名称

ordering :排序规则,按照哪个字段排unique_together序,加上负号是降序 ,ordering = ['id','-create_time']

unique_together :联合主键   unique_together = ('name','id_card')
proxy:设置True or False,设置本模型及所有继承本模型的子模型是否为代理模型;
abstract:设置True or False,设置本模型类是否为抽象基类;如果是抽象基类,那么是不会创建这张表的,这张表用来作为基类被其他的表继承

同步到数据库

1 python manage.py makemigrations #生成迁移文件
2 python manage.py migrate #同步到数据库中

QuerySet增删改查

  1 #from user.models import Category#操作哪个table就import哪个类
  2 
  3 # 运算符(不等于/大于/小于/包含)
  4 # Category.objects.filter(name__endswith='xx')#以xx结尾
  5 # Category.objects.filter(name__startswith='xx')#以xx开头
  6 # Category.objects.exclude(name="首页")#exclude-不等于,排除name="首页"的数据
  7     #多级运算,通过多层点
  8 # Category.objects.exclude(name="首页").filter(id__gte=3)#先找name !="首页",再找id>=3
  9 # Category.objects.filter(name__startswith='李').exclude(sex='女')
 10 # print(Category.objects.filter(name__contains='l'))#包含'l'
 11 # Category.objects.filter(name__icontains='l')#包含'l'或者'L',加了'i'就不区分大小写
 12 # print(Category.objects.filter(name__in=['首页','Mysql','python'])) #in
 13 
 14 
 15 # #创建
 16 # obj = models.Article.objects.create(title='title_model',desc='desc1',content='content')
 17 # obj.title = 'new_title'
 18 # obj.save()
 19 #
 20 # obj2 = models.Article(title='title_model',desc='desc1',content='content')
 21 # obj2.save()
 22 
 23 
 24 # #查询
 25 # models.Article.objects.get(id=1)#单个查询,条件只能是唯一的,否则会报错
 26 # models.Article.objects.filter(title='xiaohei',desc='desc1')#多条件查询,返回多条数据,写多个参数就是and
 27 # models.Article.objects.all().filter(title='xiaohei').values()#字典显示
 28 # models.Article.objects.all().count()#个数
 29 # models.Article.objects.raw('select * from user_article;') # 执行原生sql
 30 # models.Article.objects.filter(title__contains='模糊查询')
 31 # models.Article.objects.filter(title__endswith='开头')
 32 # models.Article.objects.filter(title__startswith='结尾')
 33 # models.Article.objects.filter(title__in=['title1','title2'])
 34 # models.Article.objects.filter(title__isnull=True)#为空
 35 # models.Article.objects.exclude(title__in=['title1','title2'])#排除
 36 # models.Article.objects.filter(read_count__gt=1)
 37 # models.Article.objects.filter(read_count__gte=1)
 38 # models.Article.objects.filter(read_count__lt=1)
 39 # models.Article.objects.filter(read_count__lte=1)
 40 # models.Article.objects.filter(read_count__range=(1,2,3))
 41 
 42 #排序
 43 #Category.objects.all().order_by("is_delete") #通过is_delete字段排序,可通过多字段排序
 44 
 45 #修改
 46 # art = models.Article.objects.get(pk=1)
 47 # art.title = 't1223'
 48 # art.save()
 49 #
 50 # models.Article.objects.filter(title__isnull=True).update(title='小黑') #批量修改
 51 # models.Article.objects.all().update(title='全部修改')#全部修改
 52 
 53 #删除
 54 # Category.objects.all().delete()#删除全表
 55     #删除某条数据
 56 # obj = Category.objects.get(id=3)
 57 # obj.delete()
 58 # obj.save()
 59     #删除部分数据
 60 # Category.objects.filter(id__in=[3,4]).delete(is_delete=False)
 61 
 62 
 63 # #外键操作
 64 # obj = models.Article.objects.get(id=1)
 65 # obj.nav_id = 2 #获取外键信息
 66 # print(obj.nav.name) #获取外键信息
 67 # models.Article.objects.filter(nav__name='abc') #按照外键的字段筛选,外键名称__字段名
 68  
 69 #反向查询
 70 # art_obj = models.Article.objects.get(pk=1)
 71 # nav_obj = models.Nav.objects.get(pk=2)
 72 # print(nav_obj.article_set.filter())#外键反向查询
 73 # print(nav_obj.article_set.count())#外键反向查询
 74 # nav_obj.article_set.add(art_obj)#添加
 75 # nav_obj.article_set.remove(art_obj)#删除
 76 # nav_obj.article_set.clear()#清空
 77  
 78 #多对多
 79  
 80  
 81  
 82 # models.CaseSet.objects.create(name='主流程用例',desc='主流程')
 83 # models.CaseSet.objects.create(name='冒烟用例',desc='冒烟用例')
 84 #
 85 # models.Case.objects.create(title='登录')
 86 # models.Case.objects.create(title='注册')
 87 # models.Case.objects.create(title='订购')
 88 # models.Case.objects.create(title='支付')
 89 # models.Case.objects.create(title='充值')
 90 # models.Case.objects.create(title='发货')
 91  
 92 # c1 = models.Case.objects.get(pk=1)
 93 # c2 = models.Case.objects.get(pk=2)
 94 # c3 = models.Case.objects.get(pk=3)
 95 # s1 = models.CaseSet.objects.get(pk=1)
 96 # s2 = models.CaseSet.objects.get(pk=2)
 97  
 98 # s2.case_set.add(c2,c3)
 99 # s2.case_set.remove(c2,c3)
100 # s2.case_set.clear()#清空
101  
102 # print(c2.case_set.all()) #查看用例在几个集合里面
103 # print(s2.case_set.all()) #查看集合里面有多少用例
104  
105  
106  
107 #一对一
108 #from hashlib import md5
109 #models.Account.objects.create(account_id=md5('niuhanyang'.encode()).hexdigest())
110 #models.Account.objects.create(account_id=md5('niuhanyang2'.encode()).hexdigest())
111 #models.Account.objects.create(account_id=md5('niuhanyang3'.encode()).hexdigest())
112  
113 # models.User.objects.create(username='niuhanyang',password='123456',account_id='58e006ecfce801c5e98311c96d32510f')
114 # u = models.User.objects.get(pk=1)
115 # print(u.account_id)
116 # print(u.account.money)
117 #
118 # acc = models.Account.objects.get(pk='58e006ecfce801c5e98311c96d32510f')
119 # print(acc.user.username)
120 # print(acc.user.password)

表结构如下图:

一对一,user表和account表

nav表,外键,一对多

case表和case_set表

原文地址:https://www.cnblogs.com/bugoobird/p/13308496.html