Django之模型层多表操作的实现


本文整理自网络,侵删。

一、创建模型

1,一对多关系

一本书只有一个出版社,一个出版社可以出版多本书,从而书与出版社之间就构成一对多关系,书是‘多'的一方,出版社是‘一'的一方,我们在建立模型的时候,把外键写在‘多'的一方,即我们要把外键写在book类。

class Book(models.Model):
 name=models.CharField(max_length=15)
 price=models.IntegerField()
 publish=models.ForeignKey('Publish',on_delete=models.CASCADE) #这就是外键,其实是有三个参数的,第二参数是指向的字段,此处可以省略,他会自动指向id字段

class Publish(models.Model):
 name=models.CharField(max_length=15)
 addr=models.CharField(max_length=15)
 phone=models.IntegerField()

在创建模型时不用创建id字段,在makemigrations命令输入之后,它会在migrations文件夹下生产一个py文件记录models.py里面所有的改动,在记录的时候就会自动给你加上自增长的主键字段id。

2,多对多关系

一本书可以有多个作者,一个作者可以写多本书,从而书和作者就构成了多对多的关系,我们在创建模型的时候,把多对多关系写在其中的任何一张表都可以。

class Book(models.Model):
 name=models.CharField(max_length=15)
 price=models.IntegerField()
 publish=models.CharField(max_length=15)
 author=models.ManyToManyField('Author',db_table='book_author')  这是创建关系表的代码,由于是写在book模型中的,所以第一个参数为另一张表Author,第二个参数为把关系表的名字改为‘book_author',如果不写,
名字会是应用名_本模型名的小写_另一张模型名的小写。如‘app_book_author'
 class Meta:  这是把表名改为‘book',如果不写,表名为APP名_模型名,如'app_book'
  db_table='book'

class Author(models.Model):
 name=models.CharField(max_length=15)
 age=models.IntegerField()
 class Meta:
  db_table='author'
在创建第三张模型的时候也不用指定book的id和author的id,它会自动把两个模型的id字段写进去的

3,一对一关系

一个作者只能对应一个作者详细信息表,他们之间就是一对一关系,这和多对多一样的,关系写在哪张表都是可以的

class Author(models.Model):
 name=models.CharField(max_length=15)
 age=models.IntegerField()
 author_info=models.OneToOneField('Author_Info',on_delete=models.CASCADE)  这是一对一关系创建,第二参数是,自动跟随删除,当作者不在了,随即作者的信息也会删除
 class Meta:
  db_table='author'
  
class Author_Info(models.Model):
 gf_name=models.CharField(max_length=10)
 telephone=models.IntegerField()
 ShenFenZheng=models.IntegerField()

4,在此处我们可以使用Django的database:db.sqlite3

步骤如下:

5,数据库迁移

由于Django默认就是db.sqlite,所以我们不用去settings配置,也不需要在项目的__init__.py里写代码,现在只需要输入两条数据库迁移指令就行了

点击这里之后进入:

在这里数输入指令,就不需要写python manage.py了,因为已经进入到manage.py

现在输入makemigrations指令 #记录models.py文件发生的改变,然后在migrations文件夹下生产一个py文件,里面记录发生的变化

再输入migrate指令 #执行migrations文件下新变动的迁移文件,去更新数据库

到此,表就创建成功了。

二、添加表记录

1,一对多关系

之前我们创建了Book表和Publish表,两者就是一对多的关系,Book表是‘多'的一方,所以外键字段在Book表,Book表添加和之前的不一样,而‘一'的Publish表就是一张单表,和之前的一样,所以我们只要学习‘多'的一张Book表的添加就行了。添加表记录有两种方式。

1.1 按models.py里面Book类的属性来添加

pub=Publish.objects.all().filter(id=1).first()  #首先找到id为1的Publish对象
book=Book.objects.create(name=name,price=price,publish=pub,pub_date=pub_date) #然后把这一对象赋值给Book类的publish属性

1.2 按数据库里面Book表的字段来添加

book=Book.objects.create(name=name,price=price,publish_id=1,pub_date=pub_date) 
#直接把Publish的id赋值给book表的publish_id就行了

2,多对多关系

之前我们创建了Book表和Author表,两者就是多对多关系,我是把多对多关系写在book表中的,所以从book去添加关联关系是正向的。

# 当前生成的书籍对象
book_obj=Book.objects.create(title="追风筝的人",price=200,publishDate="2012-11-12",publish_id=1)
# 为书籍绑定的作者对象
a1=Author.objects.filter(id=2).first() # 在Author表中主键为2的纪录
a2=Author.objects.filter(id=1).first() # 在Author表中主键为1的纪录


# 绑定多对多关系,即向关系表book_authors中添加纪录,正向用属性,反向用表名_set

第一种,以Book为基表,因为多对多关系是写在Book中的,所以现在属于正向关联,用属性
book_obj.author.add(author1,author2) #这是给book_obj对象绑定上author1和author2两个对象。这里的author不是Author小写,而是Book类的一个属性
第二种,以Author为基表,因为多对多关系不是写在Author表,所以属于反向关联,用表名小写_set
author_obj.book_set.add(book1,book2) #这是给author_obj对象绑定上book1和book2两个对象,但是这里book可不是Author类的属性,而且也没有这个属性,它是Book表小写后得到的
关系表的方法:
1,add()方法
参数可以是可以是n个模型类对象,如上面的写法
也可以是一个queryset集合,如author_list=Author.objects.filter(id__gt=2),这是找出id大于2的作者集合
book_obj.author.add(*author_list)
还可以是一个主键列表,如下面的写法
book_obj.author.add(*[1,3,4])

2,remove()方法,移出关系方法
现在book1关联着author1和author2两个作者
book1.author.remove(author1) #此时book1就关联author2一个作者
反向也行author2.book_set.remove(book2) #把author2的关联书籍book2给移出

3,clear()方法,清空关系方法
book1.author.clear()  #把book1的所有关联关系给删除,现在book1就没有关联作者了
author1.book_set.clear() 一样的,把author1的所有关联书籍的关联关系删除

4,set()方法,先把关联关系清空,再添加关联关系
假如book1关联着author1
book1.author.set(author2) 先把与author1的关联关系删除,然后再建立与author2的关联关系
假如author3关联着book1
author3.book_set.set(book2) 先把关联关系清空,再建立与book2的关联关系

5,=方法,赋值一个可迭代对象,关联关系会被整体替换
假如book1关联author1
new_list=[author2,author3]
book1.author=new_list  这也会先把关联关系清空,然后把列表里的对象与book1建立关联关系

3,一对一关系

之前创建的Author表和Author_Info表之间就是一对一关系,我把关联字段写在了Author表中。

给Author类的属性赋值
info=Author_Info.objects.create(gf_name=gf_name,telephone=telephone,ShenFenZheng=ShenFenZheng) #这是创建了一条Author_Info记录,info就是一个Author_info对象
Author.objects.create(name=name,age=age,author_info=info)  把创建的info对象赋值给author_info属性

和一对多一样,也可以使用Author表的字段赋值
Author.objects.create(name=name,age=age,author_info_id=2)

三、基于对象的跨表查询(就是子查询)

1,一对多查询(Book与Publish)

1.1 正向查询(按属性:publish)

# 查询主键为1的书籍的出版社所在的城市
book_obj=Book.objects.filter(pk=1).first()
# book_obj.publish 是主键为1的书籍对象关联的出版社对象
print(book_obj.publish.city)  

1.2 反向查询(按表名小写_set:book_set)

publish=Publish.objects.get(name="苹果出版社")
#publish.book_set.all() : 与苹果出版社关联的所有书籍对象集合
book_list=publish.book_set.all() 
for book_obj in book_list:
  print(book_obj.title)

2,一对一查询(Author与Author_Info)

2.1 正向查询(按属性:author_info)

egon=Author.objects.filter(name="egon").first()
print(egon.authorDetail.telephone)

2.2 反向查询(按表名小写:author)

# 查询所有住址在北京的作者的姓名
 
authorDetail_list=AuthorDetail.objects.filter(addr="beijing")
for obj in authorDetail_list:
  print(obj.author.name)

3,多对多查询(Author与Book)

阅读剩余部分

相关阅读 >>

Sqlitestudio打开后如何切换成简体中文Sqlitestudio绿色版中文设置方法介绍

Sqlite教程(七):数据类型详解

Sqlite数据库的介绍与java操作Sqlite的实例讲解

Sqlite教程(四):内置函数

python3 tkinkter + Sqlite实现登录和注册界面

android中Sqlite数据库知识点总结

Sqlite数据库安装及基本操作指南

python操作Sqlite数据库过程解析

centos下更新Sqlite版本

Sqlite3 使用总结

更多相关阅读请进入《Sqlite》频道 >>


数据库系统概念 第6版
书籍

数据库系统概念 第6版

机械工业出版社

本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。



打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...