欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 手游 > Django ORM(多表)

Django ORM(多表)

2025/10/25 15:15:32 来源:https://blog.csdn.net/weixin_42695345/article/details/142178723  浏览:    关键词:Django ORM(多表)

文章目录

  • 前言
  • 一、关联关系模型
  • 二、一对多写入数据
  • 二、多对多写入数据
  • 二、跨表查询
    • 1.查找'test' 标签的文章
    • 2.查找作者名为 'test' 的文章及标签
  • 三、跨表删除


前言

表与表之间的关系可分为以下三种:

一对一: 一对一关系表示一个模型的每个实例与另一个模型的每个实例都只关联一次
用 OneToOneField 来定义这种关系
一对多: 一对多关系表示一个模型的每个实例可以关联多个另一个模型的实例,但另一个模型的实例只能关联一个前者的实例
用 ForeignKey 来定义这种关系
多对多: 多对多关系表示两个模型的每个实例可以与对方的多个实例关联
用 ManyToManyField 来定义这种关系

之前我们定义了一个article模型,我们就基于这个模型实现关联关系

一、关联关系模型

更新fa下models.py

from django.db import modelsclass Tag(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=50, unique=True)created_at = models.DateTimeField(auto_now_add=True)    updated_at = models.DateTimeField(auto_now=True)def __str__(self):return self.nameclass Author(models.Model):id = models.AutoField(primary_key=True)name = models.CharField(max_length=255)email = models.EmailField(max_length=255)created_at = models.DateTimeField(auto_now_add=True)    updated_at = models.DateTimeField(auto_now=True)def __str__(self):return self.nameclass Article(models.Model):id = models.AutoField(primary_key=True)title = models.CharField(max_length=255)content = models.TextField()author = models.ForeignKey(Author, null=True, on_delete=models.CASCADE)# ManyToManyField不会直接在article表显示tag相关字段# Django 会为 ManyToManyField 创建一个中间表来存储 Article 和 Tag 之间的多对多关系# Django 会创建一个类似于 article_tags 的中间表,它包含 article_id 和 tag_id 两个字段,分别表示 Article 和 Tag 之间的关联tags = models.ManyToManyField(Tag, blank=True, related_name='articles')  # Many-to-many relationship with Tag modelcreated_at = models.DateTimeField(auto_now_add=True)    updated_at = models.DateTimeField(auto_now=True)def __str__(self):return self.title

再次生成和应用迁移:

python manage.py makemigrations
python manage.py migrate

二、一对多写入数据

views.py增加方法

def add_article(request):author = models.Author.objects.filter(pk=1).first()article = models.Article.objects.create(title="Test Article", content='123456', author=author)return HttpResponse(article)

urls.py增加路由

path('add_article', views.add_article, name='add_article')

访问链接http://127.0.0.1:8082/article/add_article
在这里插入图片描述

二、多对多写入数据

views.py里面新增方法

def add_tag(request):tag = models.Tag.objects.filter(pk=1).first()article = models.Article.objects.filter(pk=1).first()# add() 在即外键中只能传对象( *QuerySet数据类型)不能传 id(*[id表])article.tags.add(tag)return HttpResponse(article.tags.all())

urls.py增加路由

path('add_tag', views.add_tag, name='add_tag'),

访问链接http://127.0.0.1:8082/article/add_tag
刷新中间表可以看到
在这里插入图片描述

二、跨表查询

1.查找’test’ 标签的文章

新增方法

def search(request):# 查找名称为 'test' 的标签tag = models.Tag.objects.filter(name="test").first()if not tag:return HttpResponse("Tag not found")# 使用相关名称访问相关文章# Article模型设置了 related_name,则应该使用这个名称来访问反向关系。例如,如果 related_name 设置为 articles,则应使用 tag.articles.all()。# 而如果没有设置 related_name,则应该使用 tag.article_set.all()。articles = tag.articles.all()# 将结果转换为字符串以便返回articles_list = "\n".join([f"Title: {article.title}, Content: {article.content}" for article in articles])return HttpResponse(articles_list)

访问链接http://127.0.0.1:8082/article/search
在这里插入图片描述

2.查找作者名为 ‘test’ 的文章及标签

方法及路由如下

def search_by_author(request):# 查找作者名为 'test' 的作者author = models.Author.objects.filter(name="test").first()if not author:return HttpResponse("Author not found")# 查询作者的所有文章,并预取每篇文章的所有标签articles = author.article_set.prefetch_related('tags').all()# 构建文章及其标签的字符串articles_list = []for article in articles:tags = ", ".join(tag.name for tag in article.tags.all())  # 获取文章的所有标签articles_list.append(f"Title: {article.title}, Content: {article.content}, Tags: {tags}")# 将结果转换为字符串并返回return HttpResponse("\n".join(articles_list))
path('search_by_author', views.search_by_author, name='search_by_author'),

在这里插入图片描述

三、跨表删除

方法及路由如下

def delete_author_articles(request):# 查找名称为 'test' 的作者author = models.Author.objects.filter(name="test").first()if not author:return HttpResponse("Author not found")# 获取该作者下的所有文章articles = author.article_set.all()# 删除这些文章articles.delete()return HttpResponse("All articles by 'test' have been deleted")
path('delete_author_articles', views.delete_author_articles, name='delete_author_articles'),

访问链接http://127.0.0.1:8082/article/delete_author_articles
在这里插入图片描述
刷新fa_article及中间表fa_article_tags可以看到数据都被清空了

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词