Django数据库操作

在这里介绍了ORM的概念和优缺点,和基于ORM的数据库操作之增删改查。以及一对一操作,一对多操作,多对多操作。

ORM的概念


点击查看详细介绍

ORM:Object Relational Mapping(对象关系映射)

让我们从O/R开始。字母O起源于”对象”(Object),而R则来自于”关系”(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。

当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。

ORM解决的主要问题是对象关系的映射。域模型和关系模型分别是建立在概念模型的基础上的。域模型是面向对象的,而关系模型是面向关系的。一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录,类的每个属性对应表的每个字段。

ORM技术特点

  • 提高了开发效率。由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层。

  • ORM提供了对数据库的映射,不用sql直接编码,能够像操作对象一样从数据库获取数据。

ORM的缺点

ORM的缺点是会牺牲程序的执行效率和会固定思维模式。
从系统结构上来看,采用ORM的系统一般都是多层系统,系统的层次多了,效率就会降低。ORM是一种完全的面向对象的做法,而面向对象的做法也会对性能产生一定的影响。 但ORM是一种工具,工具确实能解决一些重复,简单的劳动。这是不可否认的。


在models里面创建一张表,下面的都是基于这张表的操作。

class UserInfo(models.Model):
username = models.CharField(max_length=64)
sex = models.CharField(max_length=64)
mail = models.CharField(max_length=64)

导入

from blog import models

ORM之增(create,save)

这里推荐使用第三种方式

# 增
# 第一种方式
models.UserInfo.objects.create(username='zsy1', sex='girl', mail='love.com')
# 第二种方式
obj = models.UserInfo(username='zsy2', sex='girl', mail='love.com')
obj.save()
# 第三种方式
user1 = {'username': 'zsy3', 'sex': 'girl', 'mail': 'love.com'}
models.UserInfo.objects.create(**user1)
return HttpResponse("已增加")

ORM之删

# 删
# 删除所有
models.UserInfo.objects.all().delete()
# 删除id=11的项
models.UserInfo.objects.filter(id=11).delete()
return HttpResponse("已删除")

ORM之改

推荐使用update

# 改
# 方式1 update()
models.UserInfo.objects.all().update(mail=8888)
models.UserInfo.objects.filter(id=12).update(mail=888888)

# 方式2 obj.save()
user2 = models.UserInfo.objects.get(id=12)
user2.sex = 'woman'
user2.save()
return HttpResponse("已修改")

ORM之查

# 查
# 查询所有,为QuerySet类型,可理解成列表
result = models.UserInfo.objects.all()
# 条件查询:filter 相当于where查询条件,里面的","会组成and条件
result = models.UserInfo.objects.filter(username="zsy2")
# 查看Query执行过程:
print(result.query)
# 循环打印,点号取属性值
for row in result: # 打印查询到数据。
print(row.id, row.username, row.sex)
return HttpResponse("已查找")



上面的一对一翻篇了,接下来我们学习下一对多和多对多,而我们又可以把一对多,多对多,分为正向和反向查找两种方式。
这里我们创建了两张表,在models中:

class UserType1(models.Model):
caption = models.CharField(max_length=32)

class UserInfo1(models.Model):
username = models.CharField(max_length=32)
age = models.IntegerField()
user_type = models.ForeignKey('UserType')#外键

之后再命令行执行:

python manage.py makemigrations
python manage.py migrate

这样我们就创建了两张空表:

mark

mark

正查与反查

这里ForeignKeyUserInfo表中
正向查找:如果从UserInfo表开始向其他的表进行查询,这个就是正向查询。
反向查询:如果从UserType表去查询其他的表这个就是反向操作。

ORM之一对多

增加数据

这里对user_type赋值,有两种方法:
第一种方式:再次查询数据库,不推荐

user_type = models.UserInfo1.objects.filter(id=1).first()

第二种方式:通过 外键字段_id

user_tyoe_id = 1

所以我们使用第二种创建数据:

dic = {'username': 'mosson', 'age': 18, 'user_type_id': 1}
models.UserInfo1.objects.create(**dic)
return HttpResponse('OK')

查询数据

获取到的数据类型本质上都是 queryset类型,
类似于列表,
内部有3种表现形式(对象,字典,列表)

# <QuerySet [<表名: 表 object>, <表名: 表 object>]>
modle.UserInfo1.objects.all()

注意:这里使用双下划线跨表取键值

# <QuerySet [{'xx': 'xx', 'xx': x}, {'xx': 'x', 'xx': x}]>
modle.UserInfo1.objects.values('当前表键名','跨表__键名')
# <QuerySet [('xx', x), ('xx', x)]>
modle.UserInfo1.objects.values_list('当前表键名','跨表__键名')
正向查询例子

通过UserInfo1查询:

ret = models.UserInfo1.objects.filter(user_type__caption='COO')
print(ret)
for item in ret:
print(item,item.username,item.age,item.user_type.caption)
return HttpResponse("OK")

反向查询

通过UserType1查询:
方法一:

ret = models.UserType.objects.filter(caption='COO').values('userinfo__username')
for item in ret:
print(item,type(item))

ret = models.UserType.objects.filter(caption='COO').first()
for item in ret.userinfo_set.all():
print(item.username)

总结

正向查找:

  • filter(跨表的时候,应该是对象__跨表的字段)
  • 获取这个值的时候,拿到了一行数据的时候 line.对象.跨表的字段

反向查找:

  • filter(关联这个表的表明) 自动创建和表明相同的对象,通过这个对象__跨表的字段
  • line.自动创建和表明相同的对象_set.方法

mark

ORM之多对多

首先需要说明的是:

多对多和一对多没有任何关系

创建

  • 方式一:自定义关系表

    class HostToApp(models.Model):
    hobj = models.ForeignKey(to='Host',to_field='nid')
    aobj = models.ForeignKey(to='Application',to_field='id')
  • 方式二:自动创建关系表
    表中添加 ManyToManyField

    class Application(models.Model):
    name = models.CharField(max_length=32)
    d = models.ManyToManyField("Host")


——— 未完待续 ———


-------------本文结束感谢您的阅读-------------