django-orm

Posted wenshu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django-orm相关的知识,希望对你有一定的参考价值。

  1. Django-orm定义

实现数据库的sql操作转换为接口的形式,定义的类对应mysql的表,属性对应的是数据库的字段,实例对应数据库的一条记录

 

  1. Django-orm 基础字段

2.1 所有字段都有的参数

db_column= "AA" 设置字段名称

primary_key=True 设置主键

verbose_name = "B" 设置字段别名

unique = True #设置唯一值属性

null = True blank=True # 默认情况下所有字段都不能为空,null字段设置允许为空(数据库层面),blank=True指的是前端表单提交允许为空

db_index = True 给字段建立索引

help_text = "AA" 在表单中显示说明信息

editable = False 字段不能编辑,默认字段都是可以编辑的

default = "AA" 设置默认值

 

2.2 个别字段的参数

max_length = 100 CharField必须要设置最大长度

auto_now = True DateField使用,默认填充当前时间,指的是数据更新的时间

auto_now_add = True DateField使用,指的是数据插入的时间

max_digits =4 DecimalField,设置所有的数字个数

decimal_places = 2 DecimalField,设置小数位的数字个数

 

2.3 关系型字段的参数

OneToOneField

ForeignKey

ManyToManyField

related_name = "one" 反向查询,可以通过父表查询到子表的信息

on_delete =models.CASCADE 当表关联的外键被删除时候对应的操作,一共由6种

models.CASCADE # 删除级联,删除A表的数据,B表关联的数据一起被删除

 

 

 

 

 

2.4 基础字段参数

class Test(models.Model):

 

# 自增长字段,默认是int型

Auto = models.AutoField()

BigAuto = models.BigAutoField()

 

# 二进制数据

Binary = models.BinaryField()

 

# 布尔型

Boolean = models.BooleanField() # 不允许为空的布尔

NullBoolean = models.NullBooleanField()

 

# 整型

PositiveSmallInteger = models.PositiveSmallIntegerField() # 5个字节

SmallInteger = models.SmallIntegerField()

PositiveInteger = models.PositiveIntegerField()

Integer = models.IntegerField() # 11个字节

BigInteger = models.BigIntegerField()

 

# 字符串类型

Char = models.CharField() # 需要指定默认长度

Text = models.TextField() # 不需要指定长度,可以存大量文字

 

# 时间日期类型

Date = models.DateField() # 年月日

DateTime = models.DateTimeField() # 年月日 时分秒

Duration = models.DurationField() # int型的时间

 

# 浮点型

float = models.FloatField()

Decimal = models.DecimalField()

 

# 其它字段

Email = models.EmailField() # 邮箱

Image = models.ImageField()

File = models.FileField() # 文件

FilePath = models.FilePathField() # 文件路径

URL = models.URLField()

UUID = models.UUIDField()

GenericIPAddress = models.GenericIPAddressField() # ipv4 ipv6

 

 

class Test_A(models.Model):

# 关系型字段

onetoone = models.OneToOneField(Test,on_delete=models.CASCADE)

 

class Test_B(models.Model):

foreign = models.ForeignKey(Test_A)

 

class Test_C(models.Model):

manytomany = models.ManyToManyField(Test_B)

 

 

 

 

 

 

2.5 自关联

 

class AdddressInfo(models.Model):

"省市县地址信息"

address= models.CharField(max_length=200,verbose_name="地址")

pid = models.ForeignKey("AdddressInfo",null=True,blank=True,verbose_name="自关联",on_delete=models.CASCADE)

# 可以取到这个表自己的字段

 

 

2.6 元数据

class Meta: # 每个模型类都由一个子类Meta,定义元数据的地方,封装了一些数据表的信息

db_table="address" # 定义表的名称

ordering = "pid" # 按照pid字段来排序

verbose_name = "地址" # 设置别名

verbose_name_plural = verbose_name # 设置别名复数

abstract = True # 设置这个类为基类,仅供其它类继承,自身不生成表

 

 

2.7 取choice里面的显示值

type = models.CharField(choices=((0,‘test00‘),(1,‘test11‘),(2,‘test22‘)))

 

def __str__(self):

return self.address+self.get_type_display()

# 在数据库实际存储的是 0,1,2,但是页面展示的是test00 test11 test22,但是在数据库取值的时候可以通过 get+字段名+display() 的方式取值(django orm方法)

 

2.8 表结构

所以可以科学的删除数据表(了解了makemigrations migrate 的用处)

makemigrations: 通过models生成一个表执行文件到migrations文件夹下面

migrate:执行这个表执行文件(生成或者修改表记录)

 

 

2.9 数据的创建

bulk_create : 批量导入

update_or_create: 创建或者更新

get_or_create: 取值或者创建

当导入的表结构含有外键属性的时候: 可以直接使用

teacher = Teacher.object.get(A="A") teacher 是course表的字段,Teacher是course的关联表。

 

 

 

  1. QuerySet api

3.1返回新的QuerySet api

1. all() get() order_by() exclude() reverse() distinct()

exclude() 排除指定条件的结果集

 

 

2. values() values_list() 获取字典或者元组形式的QuerySet

例如:

Teacher.Objects.values("nickname","111")

>>> [{"nickname":"别名","111":"123"},{},{}] 字典格式的QuerySet

>>> [("nickname":"别名","111":"123"),(),()] 元组格式的QuerySet

 

 

3. 反向查询通过父表查询子表

 

子表查询父表的数据:

当导入的表结构含有外键属性的时候: 可以直接使用

teacher = Teacher.object.get(A="A") teacher 是course表的字段,Teacher是course的关联表。

 

父表查询子表的数据:

Teacher.objects.get(A="A").course_set.all() Teacher是父表,course是子表,格式是(子表名_set)

 

 

3.2 不返回QuerySet Api

 

get() 查询单个对象

get_or_create() 查询或者创建

Author.objects.get_or_create(nickname="hello",default={"name":"123"})

备注:主键或者唯一键写在外面,如果有,获取返回的值;没有,使用default里面的值创建

 

create() 创建

bulk_create() 批量创建 传的值是列表

update_or_create() 创建或更新,用法同get_or_create()

update() 更新

delete() 删除

exist() 判断是否存在

count() 计数

 

 

 

3.3 F对象和Q对象

F对象的使用:操作字段的数据

Q对象: 结合AND OR NOT | ~ & 实现复杂的查询

& 与

| 或

NOT 取反

 

 

  1. 其它

4.1新建一个对象的方法有以下几种:

# 方法 1

Author.objects.create(name="WeizhongTu", email="tuweizhong@163.com")

 

# 方法 2

twz = Author(name="WeizhongTu", email="tuweizhong@163.com")

twz.save()

 

# 方法 3--------------------常用

twz = Author()

twz.name="WeizhongTu"

twz.email="tuweizhong@163.com"

twz.save()

 

# 方法 4,首先尝试获取,不存在就创建,可以防止重复

Author.objects.get_or_create(nickname="hello",default={"name":"123"})

备注:主键或者唯一键写在外面,如果有,获取返回的值;没有,使用default里面的值创建

# 返回值(object, True/False)

 

 

 

备注:前三种方法返回的都是对应的 queryset object,最后一种方法返回的是一个元组,(object, True/False),创建时返回 True, 已经存在时返回 False

 

 

 

4.2 获取对象有以下方法

Person.objects.all() # 返回QuerySet结果集

Person.objects.all()[:10] 切片操作,获取10个人,不支持负索引,切片可以节约内存

Person.objects.get(name=name) ## 名称为 WeizhongTu 的一条,多条会报错

 

A:get是用来获取一个对象的,get返回的是结果,如果获取到多个会报错,通常传主键或者唯一键作为查询条件

B:filter获取满足条件的一些结果,filter返回的是结果集(QuerySet,类似于list,可以使用for循环来取值,支持切片))

 

 

Person.objects.filter(name="abc",address = "北京")  Person.objects.filter(name__exact="abc") 名称严格等于 "abc" 的人

A:逗号代表与的关系,

B:mes= Person.objects.filter(name="abc",address = "北京") #返回queryset对象,获取不到返回None

print(mes.name) #返回的是多条记录的对象[object1,object2,objevt3],对象有字段的方法 mes.name

C: 字段__+关键字(对字段进行特殊orm操作:)

例如: name__exact="abc" 刚好等于

name__gte = 大于

name__in= 在列表范围内

D:Person.objects.all().order_by("字段名") 以。。进行排序(默认升序排列)

Person.objects.all().order_by("-字段名") 降序排列

E:查看原生的SQL

str(Person.objects.all().order_by.query)

 

 

Person.objects.filter(name__iexact="abc")  # 名称为 abc 但是不区分大小写,可以找到 ABC, Abc, aBC,这些都符合条件

 

Person.objects.filter(name__contains="abc")  # 名称中包含 "abc"的人

Person.objects.filter(name__icontains="abc")  #名称中包含 "abc",且abc不区分大小写,模拟sql中like语句

 

Person.objects.filter(name__regex="^abc")  # 正则表达式查询

Person.objects.filter(name__iregex="^abc")  # 正则表达式不区分大小写

 

filter是找出满足条件的,当然也有排除符合某条件的

Person.objects.exclude(name__contains="WZ")  # 排除包含 WZ 的Person对象

Person.objects.filter(name__contains="abc").exclude(age=23)  # 找出名称含有abc, 但是排除年龄是23岁的

 

 

4.3删除符合条件的结果

 

和上面类似,得到满足条件的结果,然后 delete 就可以(危险操作,正式场合操作务必谨慎),比如

Person.objects.filter(name__contains="abc").delete() # 删除 名称中包含 "abc"的人

 

如果写成 

people = Person.objects.filter(name__contains="abc")

people.delete()

效果也是一样的,Django实际只执行一条 SQL 语句。

 

 

4.4更新某个内容

(1) 批量更新,适用于 .all()  .filter()  .exclude() 等后面 (危险操作,正式场合操作务必谨慎)

1

2

Person.objects.filter(name__contains="abc").update(name=‘xxx‘) # 名称中包含 "abc"的人 都改成 xxx

Person.objects.all().delete() # 删除所有 Person 记录

(2) 单个 object 更新,适合于 .get(), get_or_create(), update_or_create() 等得到的 obj,和新建很类似。

1

2

3

4

twz = Author.objects.get(name="WeizhongTu")

twz.name="WeizhongTu"

twz.email="tuweizhong@163.com"

twz.save()  # 最后不要忘了保存!!!

 

 

QuerySet 是可迭代的,比如:

es = Entry.objects.all()

for e in es:

    print(e.headline)

Entry.objects.all() 或者 es 就是 QuerySet 是查询所有的 Entry 条目。

 

注意事项:

(1). 如果只是检查 Entry 中是否有对象,应该用 Entry.objects.all().exists()

(2). QuerySet 支持切片 Entry.objects.all()[:10] 取出10条,可以节省内存

(3). 用 len(es) 可以得到Entry的数量,但是推荐用 Entry.objects.count() (等价于 es.count())来查询数量,后者用的是SQL:SELECT COUNT(*)

(4). list(es) 可以强行将 QuerySet 变成 列表

 

以上是关于django-orm的主要内容,如果未能解决你的问题,请参考以下文章