zoukankan      html  css  js  c++  java
  • Django(15)外键和表关系

    外键删除操作

    如果一个模型使用了外键。那么在对方那个模型被删掉后,该进行什么样的操作。可以通过on_delete来指定。可以指定的类型如下:

    1. CASCADE:级联操作。如果外键对应的那条数据被删除了,那么这条数据也会被删除。
    2. PROTECT:受保护。即只要这条数据引用了外键的那条数据,那么就不能删除外键的那条数据。
    3. SET_NULL:设置为空。如果外键的那条数据被删除了,那么在本条数据上就将这个字段设置为空。如果设置这个选项,前提是要指定这个字段可以为空
    4. SET_DEFAULT:设置默认值。如果外键的那条数据被删除了,那么本条数据上就将这个字段设置为默认值。如果设置这个选项,前提是要指定这个字段一个默认值。
    5. SET():如果外键的那条数据被删除了。那么将会获取SET函数中的值来作为这个外键的值。SET函数可以接收一个可以调用的对象(比如函数或者方法),如果是可以调用的对象,那么会将这个对象调用后的结果作为值返回回去。
    6. DO_NOTHING:不采取任何行为。一切全看数据库级别的约束。

    注意:以上这些选项只是Django级别的,数据级别依旧是RESTRICT
     

    表关系

    表之间的关系都是通过外键来进行关联的。而表之间的关系,无非就是三种关系:一对一、一对多、多对多等。以下将讨论一下三种关系的应用场景及其实现方式。
     

    一对多

    应用场景:比如文章和作者之间的关系。一个文章只能由一个作者编写,但是一个作者可以写多篇文章。文章和作者之间的关系就是典型的多对一的关系
    实现方式:一对多,都是通过ForeignKey来实现的。

    class User(models.Model):
        username = models.CharField(max_length=20)
        password = models.CharField(max_length=100)
    
    class Article(models.Model):
        title = models.CharField(max_length=100)
        content = models.TextField()
        author = models.ForeignKey("User",on_delete=models.CASCADE)
    

    那么以后在给Article对象指定category,就可以使用以下代码来完成:

    article = Article(title='abc',content='123')
    author = User(username='jkc',password='123456')
    # 要先保存到数据库中
    author.save()
    article.author = author
    article.save()
    

    并且以后如果想要获取某个种类下所有的文章,可以通过article_set来实现。示例代码如下:

    user = User.objects.first()
    # 获取第一个用户写的所有文章
    articles = user.article_set.all()
    for article in articles:
        print(article)
    

    一对一

    1. 在Django中一对一是通过models.OnetToOneField来实现的。这个OneToOneField其实本质上就是一个外键,只不过这个外键有一个唯一约束(unique key),来实现一对一。
    2. 以后如果想要反向引用,那么是通过引用的模型的名字转换为小写的形式进行访问。比如以下模型:
     class FrontUser(models.Model):
         username = models.CharField(max_length=200)
    
     class UserExtension(models.Model):
         school = models.CharField(max_length=100)
         user = models.OneToOneField("FrontUser",on_delete=models.CASCADE)
    
     # 通过userextension来访问UserExtension对象
     user = FrontUser.objects.first()
     print(user.userextension)
    

    UserExtension的对象,可以通过user来访问到对应的user对象。并且FrontUser对象可以使用userextension来访问对应的UserExtension对象。 如果不想使用Django默认的引用属性名字。那么可以在OneToOneField中添加一个related_name参数。示例代码如下:

     class FrontUser(models.Model):
         username = models.CharField(max_length=200)
    
     class UserExtension(models.Model):
         school = models.CharField(max_length=100)
         user = models.OneToOneField("FrontUser",on_delete=models.CASCADE,related_name='extension')
    
     # 通过extension来访问到UserExtension对象
     user = FrontUser.objects.first()
     print(user.extension)
    

    那么以后就FrontUser的对象就可以通过extension属性来访问到对应的UserExtension对象。
     

    多对多

    1. 应用场景:比如文章和标签的关系。一篇文章可以有多个标签,一个标签可以被多个文章所引用。因此标签和文章的关系是典型的多对多的关系。
    2. 实现方式:Django为这种多对多的实现提供了专门的Field。叫做ManyToManyField。还是拿文章和标签为例进行讲解。示例代码如下:
     class Article(models.Model):
         title = models.CharField(max_length=100)
         content = models.TextField()
         tags = models.ManyToManyField("Tag",related_name="articles")
    
     class Tag(models.Model):
         name = models.CharField(max_length=50)
    

    在数据库层面,实际上Django是为这种多对多的关系建立了一个中间表。这个中间表分别定义了两个外键,引用到articletag两张表的主键。
    在我们使用多对多反向引用添加的时候,只能使用add这种添加方式,比如向文章中添加标签,示例代码如下:

    article = Article.objects.first()
    tag = Tag(name="好看")
    tag.save()
    article.tag_set.add(tag)  # 向文章中添加标签tag
    
  • 相关阅读:
    NC 工具的使用教程
    centos7&redhat 之 firewalld 详细介绍配置
    rabbitmq&&erlang 安装
    centos7 rabbitmq 安装
    Centos7 Erlang Solutions 安装
    CentOS7 LVM添加硬盘及扩容
    Linux服务器上监控网络带宽的18个常用命令
    在PowerDesigner中自动生成sqlserver字段备注
    JS 验证URL
    GitHub上整理的一些工具【转载】
  • 原文地址:https://www.cnblogs.com/jiakecong/p/14777061.html
Copyright © 2011-2022 走看看