57.表关系一对多使用详解

Posted guyan-2020

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了57.表关系一对多使用详解相关的知识,希望对你有一定的参考价值。

1.应用场景:比如一个文章的分类中可以含有多篇文章 ,但是一篇文章只能属于一个分类,这就是典型的一对多关系。
2.实现方式 :一对多或者是多对一,都是通过“ForeignKey”来实现的,在这里以文章和分类的案例进行讲解。
articleAPP中models.py中定义模型,示例代码如下:
from django.db import models


class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    #  可以指定默认值,同样也可以指定null=True,因为默认情况下,null=False
    # 可以修改models.name_set名字,通过Foreign_key()中的属性,related_name
    author = models.ForeignKey('frontuser.User', on_delete=models.CASCADE, default=1)
    # 应用不同app中定义的模型,可以通过指定‘app名.模型名’
    category = models.ForeignKey('frontuser.Category', on_delete=models.CASCADE, default=1, related_name='articles')

    def __str__(self):
        return "<(Article: (id: %s, title: %s, content: %s, author: %s, category: %s))>" %                (self.id, self.title, self.content, self.author, self.category)
frontuserAPP中models.py文件中示例代码如下:
from django.db import models


class User(models.Model):
    name = models.CharField(max_length=20, default=1)
# 重写类的__str__(str)方法,在调用类的时候就会执行__str__(self)方法。
    def __str__(self):
        return "<(User: (id: %s, name: %s))>" % (self.id, self.name)


class Category(models.Model):
    name = models.CharField(max_length=100, default=1)
# 重写类的__str__(self)方法
    def __str__(self):
        return "<(Category: (id: %s, name: %s))>" % (self.id, self.name)
在article中的views.py文件中,示例代码如下:
from django.shortcuts import render
from django.http import HttpResponse
from .models import Article
from frontuser.models import User,Category


def index(request):
    # 添加用户数据信息
    # user = User(name='小蚂蚁')
    # user.save()
    #
    # # 2.category数据信息添加
    # category = Category(name='国际新闻')
    # category.save()
    #
    # # 3.article信息添加
    # article = Article(title='美国大选', content='女士们,先生们..')
    # article.save()
    return HttpResponse("success")


def one_to_many(request):
    # 1.添加一条数据,表与表之间的关系一对多
    # article = Article(title='习大大慰问', content='同志们好')
    # user = User.objects.first()
    # category = Category.objects.first()
    #
    # article.author = user
    # article.category = category
    # article.save()

    # 2.修改文章信息
    # article = Article.objects.get(title='美国大选')
    # category = Category.objects.get(name='国际新闻')
    # article.category = category
    # article.save()

    # 3.查找某个分类下所有的文章
    # 如果一个模型被其他的模型进行引用了,就会为这个模型添加一个方法为:
    # 被引用模型名小写字母_set,这个方法的使用和objects方法很相似
    # category = Category.objects.first()
    # # 得出的信息为RelateManager
    # article = category.article_set.first()
    # #  重写所有模型的__str__(self)方法
    # print(article)

    # 4.通过另外一种方法,将某一篇文章添加到某个分类中
    # 同样,被引用的模型下的models.name_set方法可以被重新定义为一个新的名字
    # 在模型中的ForeignKey()中有一个参数为 related_name,可以通过这个参数来更改
    # category = Category.objects.first()
    # article = Article(title='阿里巴巴', content='扫福活动')
    # article.author = User.objects.first()
    # article.save()
    #
    # # 将文章添加到分类中
    # category.articles.add(article)
    # category.save()

    # 5.在我们的对象还没有 保存,我们可以通过指定bluk=False,来让Django底层去保存
    # 再添加一篇文章,示例
    category = Category.objects.get(pk=3)
    article = Article(title='特朗普今日活动', content='保镖...')
    article.author = User.objects.get(pk=3)
    category.articles.add(article, bulk=False)
    return HttpResponse("添加成功")

*使用“bulk=False”,那么Django就会自动保存article,而不需要在添加到category之前 先保存article。或者是另外一种解决方式是,在添加到"category.article_set"中之前,先将“article”保存到数据库中,但是此时如果 “article.category”不能为空,那么就会产生一种死循环了,即article没有 "category"不能进行保存,而将article添加到"category.article_set"中,有需要article之前是已经存储到数据库中的。
查看数据库中article表中的数据信息:
技术图片

以上是关于57.表关系一对多使用详解的主要内容,如果未能解决你的问题,请参考以下文章

关于JPA一对一,一对多(多对一),多对多的详解

(原创)hibernate 一对多建表实例详解 附上各个注释的含义

Java web 作业6 答案详解

一对多和递归关系 - 强制设置值

iOS 核心数据关系一对多 vs. fetchedResultsController 速度

同一实体类型代码的多个一对多关系优先