// Fork me on GitHub

Django 表关系的创建 以及数据的增删改查

我们知道,表关系分为一对多,多对多,一对一


我们以一个图书管理系统为背景,设计了下述四张表,让我们来找一找它们之间的关系

Book与Publish表

找关系:一对多

复制代码
左表(Book)<------------------------------->右表(Publish)

# 步骤一:
#分析1、先站在左表的角度
左表的多条记录代表多本书籍,右表的一条记录代表一个出版社,多本书籍对应同一个出版社 ✔️

#分析2、再站在右表的角度去找
右表的多条记录代表多个出版社,左表的一条记录代表一本书,多个出版社不能出版同一本书 ✘

# 步骤二:后确定关系
# 一对多
左表多对一右表,关联字段应该创建在BOOk表中,然后foreign key 右表
复制代码

Book与Author表

关系:多对多

两者之间是多对多的外键关系,需要创建一张单独的新表来专门存放二者的关系,外键字段推荐建在查询频率较高的那种表中

Author表与AuthorDetail表

关系:一对一

作者与作者详情是一对一的外键关系,外键字段推荐建在查询频率较高的那种表中

复制代码
class Book(models.Model):
    # 因为id是自动创建,所以可以不写
    title =models.CharField(max_length=64)
    #price为小数字段,总共8位数,小数位占2位
    price = models.DecimalField(max_digits=8,decimal_places=2)

    # 书籍与出版社  是一对多外键关系
    publish = models.ForeignKey(to='Publish')  # 默认关联字段就是出版社表的主键字段
    # publish = models.ForeignKey(to=Publish)
    # to后面也可以直接写表的变量名 但是需要保证该变量名在当前位置的上方出现

    # 书籍与作者  是多对多外键关系
    authors = models.ManyToManyField(to='Author')
    """
    authors字段是一个虚拟字段 不会真正的在表中创建出来
    只是用来告诉django orm 需要创建书籍和作者的第三张关系表
    """

class Publish(models.Model):
    name = models.CharField(max_length=64)
    addr = models.CharField(max_length=64)

class Author(models.Model):
    name =models.CharField(max_length=32)
    phone = models.BigIntegerField()
    # 一对一外键关系建立
    author_detail = models.OneToOneField(to='AuthorDetail')

class AuthorDetail(models.Model):
    age = models.IntegerField()
    addr = models.CharField(max_length=255)

注意:"""
    ForeignKey字段以及OneToOneField字段 在创建表的时候orm都会自动给该字段加_id的后缀
    无论自己有没有加
   """

复制代码

 

多对多关联关系的三种方式

方式一:全自动创建第三张表

 方式二:纯手动创建(了解)

 

  方式三:半自动创建(推荐)

django请求生命周期流程图

 

 
 补充:
创建表  

```python
一对一   实际上是创建了一个字段
    xx = models.OneToOneField(to='表名',to_field='字段名',on_delete=models.CASCADE)  #删除时的一些级联效果,to_field可以不写,默认是关联到另一张表的主键,
                                                  on_delete在1.x版本的django中不用写,默认是级联删除的,2.x版本的django要写.
一对多 创建字段和外键 xx = models.ForeignKey(to='表名',to_field='字段名',on_delete=models.CASCADE) 多对多 xx = models.ManyToManyField(to='另外一个表名') #这是自动创建第三表 示例 from django.db import models # Create your models here. from django.db import models # Create your models here. #作者表 class Author(models.Model): #比较常用的信息放到这个表里面 name=models.CharField( max_length=32) age=models.IntegerField() # authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE) authorDetail=models.OneToOneField(to='AuthorDetail') #一对一到AuthorDetail表 生成为表字段之后,会自动变为authorDetail_id这样有一个名称 # 外键字段 -- 外键字段名_id # foreign+unique def __str__(self): return self.name #作者详细信息表 class AuthorDetail(models.Model): birthday=models.DateField() # telephone=models.BigIntegerField() telephone=models.CharField(max_length=32) addr=models.CharField( max_length=64) def __str__(self): return self.addr #出版社表 和 书籍表 是 一对多的关系 class Publish(models.Model): name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() #charfield -- asdfasdf def __str__(self): return self.name #书籍表 #外键根部所在的表比较被动 class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) #decimal(5,2) publishs=models.ForeignKey(to="Publish") authors=models.ManyToManyField(to='Author',) def __str__(self): return self.title #手动创建第三张表,暂时忽略 # class BookToAuthor(models.Model): # book_id = models.ForeignKey(to='Book') # author_id = models.ForeignKey(to='Author') # # xx = models.CharField(max_length=12) ``` # manytable60/admin django后台往数据库里添加数据 一种 方式 # #创建表的方式https://www.cn.blogs.com/clschao/articles/10439958.html

增删改查 django多表里也有这部分内容 增 ``` #1 增 #1.1 一对一增加 #外键的根部是比较被动的表,那么首先要先创建箭头指向的表,然后在关联一下 # new_author_detail = models.AuthorDetail.objects.create( # birthday='1979-08-08', # telephone='138383838', # addr='黑龙江哈尔滨' # ) # obj = models.AuthorDetail.objects.filter(addr='山西临汾').first() #方式1 # models.Author.objects.create( # name='王涛', # age='40', # authorDetail=new_author_detail, # ) # 方式2 常用 # models.Author.objects.create( # name='王涛', # age='40', # authorDetail_id=obj.id, # ) # 一对多 #方式1 # obj = models.Publish.objects.get(id=2) #先创建箭头所指的对象 # models.Book.objects.create( # title = '李帅的床头故事', # publishDate='2019-07-22', # price=3, # # publishs=models.Publish.objects.get(id=1), # publishs=obj, # # ) # 方式2 常用 # models.Book.objects.create( # title='李帅的床头故事2', # publishDate='2019-07-21', # price=3.5, # # publishs=models.Publish.objects.get(id=1), # publishs_id=obj.id # # ) # 多对多 # 方式1 常用 # book_obj = models.Book.objects.get(nid=1) # book_obj.authors.add(*[1,2]) # 方式2 # author1 = models.Author.objects.get(id=1) # author2 = models.Author.objects.get(id=3) # book_obj = models.Book.objects.get(nid=5) # book_obj.authors.add(*[author1,author2]) ``` 删 ``` 一对一和一对多的删除和单表删除是一样的 删到箭头是有影响的 # 一对一 表一外键关联到表二,表一删除,不影响表2,表2删除会影响表1 # models.AuthorDetail.objects.get(id=2).delete() # models.Author.objects.get(id=3).delete() # 一对多 # models.Publish.objects.get(id=1).delete() # models.Book.objects.get(nid=1).delete() # 多对多关系删除 # book_obj = models.Book.objects.get(nid=6) # book_obj.authors.remove(6) a_obj1 # book_obj.authors.remove(*[5,6]) # book_obj.authors.clear() # book_obj.authors.add(*[1,]) # book_obj.authors.set('1') # book_obj.authors.set(['5','6']) #删除然后更新 ``` 更新 ``` # 更新 外键没有默认即连更新 update是queryset才能调用的方法 # 一对一 # models.Author.objects.filter(id=5).update( # name='崔老师', # age=16, # # authorDetail=models.AuthorDetail.objects.get(id=5), # authorDetail_id=4, # ) #一对多 # models.Book.objects.filter(pk=4).update( # title='B哥的往事2', # # publishs=models.Publish.objects.get(id=3), # publishs_id=3, # ) #一对多 models.Publish.objects.filter(pk=2).update( id=4, # django没有默认即连更新,报错!! 需要数据库中进行操作 ) ```

 

 
 
 
 
 
posted @ 2020-10-11 12:05  繁星春水  阅读(354)  评论(0编辑  收藏  举报
1 //2 3
//4