16.表关系

 

一对多

  1. 应用场景:好比文章和做者之间的关系。一个文章只能由一个做者编写,可是一个做者能够写多篇文章。文章和做者之间的关系就是典型的多对一的关系。
  2. 实现方式:一对多或者多对一,都是经过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对象指定author,就可使用如下代码来完成:javascript

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

而且之后若是想要获取某个用户下全部的文章,能够经过article_set来实现。示例代码以下:html

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

而且若是想要将文章添加到某个分类中。可使用一下的方式:java

category = Category.objects.first()

article = Article(title='bbb',content='vvv')
article.author = FrontUser.objects.first()

category.article_set.add(article,bulk=False)


使用bulk=False,那么Django会自动的保存article,而不须要在添加到category以前先保存article。
或者是另一种解决方式是,在添加到category.article_set中以前,先将article保存到数据库中。可是若是article.category不能为空,那么就产生一种死循环了,article没有category不能保存,而将article添加到cateogry.artile_set中,又须要article以前是已经存储到数据库中的。
* 若是是上面的那种需求,建议使用bulk=False的解决方案。python

一对一

  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. 应用场景:好比文章和标签的关系。一篇文章能够有多个标签,一个标签能够被多个文章所引用。所以标签和文章的关系是典型的多对多的关系。ios

  2. 实现方式:Django为这种多对多的实现提供了专门的Field。叫作ManyToManyField。仍是拿文章和标签为例进行讲解。示例代码以下:web

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两张表的主键。数据库

相关文章
相关标签/搜索