zoukankan      html  css  js  c++  java
  • ORM多表操作之创建关联表及添加表记录

    创建关联表

    关于表关系的几个结论

    (1)一旦确立表关系是一对多:建立一对多关系————在多对应的表中创建关联字段。
    (2)一旦确立表关系是多对多:建立多对多关系————创建第三张关系表————id和两个关联字段。
    (3)一旦确定表关系是一对一:建立一对一关系————在两张表的任意一张表中建立关联字段+Unique。
    (4)其实上面说的“关联字段”就是外键——foreign key。

    本文用到的表、字段及相互关系

    (1)作者模型:一个作者有姓名和年龄。
    (2)作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息:作者详情模型和作者模型之间是一对一的关系(one-to-one)
    (3)出版社模型:出版社有名称,所在城市以及email。
    (4)书籍模型: 书籍有书名和出版日期.一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);另外一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)
    (5)书跟作者是多对多关系,利用Django的建表语句我们可以新生成一张“关系表”——book2author

    建表过程

    models.py文件中的内容如下:
    from django.db import models
    
    #出版社
    class Publish(models.Model):
    	#主键
    	nid = models.AutoField(primary_key=True)
    	name = models.CharField(max_length=55)
    	city = models.CharField(max_length=55)
    	#email有特定的格式!
    	email = models.EmailField()
    
    #作者详细
    class AuthorDetail(models.Model):
    	nid = models.AutoField(primary_key=True)
    	#日期的格式
    	birthday = models.DateField()
    	#手机号
    	telephone = models.BigIntegerField()
    	addr = models.CharField(max_length=55)
    
    #作者表
    class Author(models.Model):
    	nid = models.AutoField(primary_key=True)
    	name = models.CharField(max_length=55)
    	#年龄,int类型的小数字就可以
    	age = models.IntegerField()
    	#由于作者与作者详细表是一对一的关系:所以选择在作者表中这样建立外键
    	#注意这里还是只写authordetail就可以了,_id 程序会自动给加的!
    	#注意这里on_delete一定要加!而且to后面的表的名字要习惯性的加上1
    	#一对一!
    	authordetail = models.OneToOneField(to='AuthorDetail',to_field='nid',on_delete=models.CASCADE)
    
    
    #书籍
    class Book(models.Model):
    	nid = models.AutoField(primary_key=True)
    	title = models.CharField(max_length=55)
    	#出版日期,日期格式
    	pub_date = models.DateField()
    	#价格,最大位数5位,小数后保留两位
    	price = models.DecimalField(max_digits=5,decimal_places=2)
    	#与出版社表关联的字段——publish_id
    	#注意自己写的时候只写publish就可以了!Django会自动补上_id
    	#注意:on_delete必须要加上!!!而且to后面的表的名字要习惯性的加上1
    	#注意 null=true表示允许为空值
    	# 一对多!
    	publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE,null=True)
    	#书跟作者是多对多的关系。理论上需要新建一张关系表。
    	#但是利用Django下面的语句既可以新建一张表,又可以分别将其与书籍表与作者表关联起来!
    	#多对多!
    	authors = models.ManyToManyField(to='Author')
    	'''
    	create table book2author(
    		id int primary_key auto_increment,
    		book_id int,
    		author_id int,
    		foreign_key (book_id) references Book(id),
    		foreign_key (author_id) references Author(id),   
    	);
    	'''
    
    接着,我们在terminal中运行:
    python manage.py makemigrations
    python manage.py migrate
    
    效果如下:


    最后我们在数据库中可以看到生成了5张表(建议大家用Navicat工具):

    注意事项:
    (1)表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称  
    (2)id字段是自动添加的
    (3)对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
    (4)这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
    (5)定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。
    (6)外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 
    

    添加表记录

    为了方便,建议大家事先在publish、author、authordetail表中加几条数据。

    一对多关系添加记录:

    在book表中新增一条记录,由于publish表与book表是一对多的关系,关联字段为publish_id,因此我们先得找到对应的出版社,这里有两种方法:
    方法一:
    publish_obj = Publish.objects.get(nid=1)
    Book.objects.create(title='三国',price=100,pub_date='1922-2-3',publish=publish_obj)
    
    方法二:
    Book.objects.create(title='三国',price=100,pub_date='1922-2-3',publish_id=1)
    
    注意理解这里的publish_obj
    一个简单的查询:查看水浒传书籍的出版社对应的邮箱——
    book_boj = Book.objects.filter(title='水浒传').first()
    ret = book_obj.publish.email
    print(ret)
    

    多对多关系添加记录

    书籍与作者是多对多的关系。创建一个book记录,将两个作者关联到这个记录中,表示这两个作者写同一本书。
    ##注意这里的first()
    book_obj = Book.objects.create(title='三国群英传2',price=200,pub_date='1900-3-4',publish_id=2)
    whw = Author.objects.filter(nid=1).first()
    www = Author.objects.filter(nid=2).first()
    ##绑定多对多关系的API。
    ##这个authors就是Book类里建多对多关系的时候的那个:authors = models.ManyToManyField(to='Author')
    book_obj.authors.add(whw,www)
    

    解除多对多关系

    ##解除多对多关系,注意first得加
    book = Book.objects.filter(nid=4).first()	
    ##注意这里的2代表author_id
    book.authors.remove(2)
    ##也可以移除所有的关系:
    book.authors.clear()
    

    all()方法:

    all()方法是这里一个比较重要的API,我们如果想得到某一本书所有的作者对象的集合可以这样做:
    book = Book.objects.filter(nid=1).first()
    ret = book.authors.all()
    print(ret)
    
    注意这里得出的ret是一个QuerySet对象,是与这本书关联的所有作者对象的集合
    如果我们想查询主键为4的书籍的所有作者的名字,可以这样做:
    book_obj = Book.objects.filter(nid=4).first()
    rets = book_obj.authors.all().values('name')
    print(rets)
    
    得到的结果是:<QuerySet [{'name': 'whw'}, {'name': 'www'}]>
    最后需要提醒大家一点:
    本文略去了项目创建以及文件配置的过程,如需查看这部分内容,请大家看一下我上一篇文章https://www.cnblogs.com/paulwhw/p/9395085.html
  • 相关阅读:
    EL表达式(Expression Language)
    JSP简单功能介绍
    MySQL基础使用
    JDBC
    MySQL安装卸载
    stanfordnlp dependencies(依存关系简写表)
    不需要深度学习就能做的文本分类器
    词向量的cbow模型
    pytorch实现自己的textCNN
    OpenCV编译viz模块
  • 原文地址:https://www.cnblogs.com/paulwhw/p/9405168.html
Copyright © 2011-2022 走看看