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
  • 相关阅读:
    Educational Codeforces Round 86 (Rated for Div. 2) D. Multiple Testcases
    Educational Codeforces Round 86 (Rated for Div. 2) C. Yet Another Counting Problem
    HDU
    HDU
    HDU
    HDU
    Good Bye 2019 C. Make Good (异或的使用)
    Educational Codeforces Round 78 (Rated for Div. 2) C. Berry Jam
    codeforces 909C. Python Indentation
    codeforces1054 C. Candies Distribution
  • 原文地址:https://www.cnblogs.com/paulwhw/p/9405168.html
Copyright © 2011-2022 走看看