Django 多对多关系

多对多关系作用

Django 中,多对多关系模型的作用主要是为了表示两个模型之间的多对多关系。具体来说,多对多关系允许一个模型的实例与另一个模型的多个实例相关联,反之亦然。这在很多实际应用场景中非常有用,比如:

  1. 博客和标签:一篇博客文章可以有多个标签,一个标签也可以属于多篇博客文章。
  2. 学生和课程:一个学生可以选修多门课程,一门课程也可以有多个学生选修。
  3. 作者和书籍:一本书可以有多个作者,一个作者也可以写多本书。

以下实现简易博客和标签的示例

1,创建应用

Test/app10

复制代码
python manage.py startapp app10

2,注册应用

Test/Test/settings.py

4,添加路由

Test/Test/urls.py

复制代码
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('app9.urls')),
    # ...
    path('app10/', include('app10.urls')),
]

5,添加模型

Test/app10/models.py

复制代码
from django.db import models

class Tag(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    tags = models.ManyToManyField(Tag, related_name='posts')

    def __str__(self):
        return self.title

6,执行迁移

复制代码
python manage.py makemigrations app10
python manage.py migrate app10

7,添加视图函数

Test/app10/views.py

复制代码
from django.shortcuts import render
from .models import Post

def post_list(request):
    posts = Post.objects.all()
    return render(request, '10/post_list.html', {'posts': posts})

8,添加html代码

Test/templates/10/post_list.html

复制代码
<!DOCTYPE html>
<html>
<head>
    <title>Blog</title>
</head>
<body>
    <h1>Blog Posts</h1>
    <ul>
        {% for post in posts %}
            <li>
                <h2>{{ post.title }}</h2>
                <p>{{ post.content }}</p>
                <p>Tags:
                    {% for tag in post.tags.all %}
                        {{ tag.name }}{% if not forloop.last %}, {% endif %}
                    {% endfor %}
                </p>
            </li>
        {% endfor %}
    </ul>
</body>
</html>

9,添加应用路由

Test/app10/urls.py

复制代码
from django.contrib import admin
from django.urls import path
from app10 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('post_list', views.post_list, name='post_list'),
]

10,管理台添加数据

http://127.0.0.1:8000/admin/

添加标签

添加文章并关联标签

11,访问页面

http://127.0.0.1:8000/app10/post_list

12,查看数据库

app10_tag 标签表

app10_post 文章表

app10_post_tags

可以看到app10_post_tags表关联另外两张表的id,建立了多对多的关系关系

13,删除文章

13.1 添加删除文章视图函数

Test/app10/views.py

复制代码
from django.shortcuts import render
from .models import Post

def post_list(request):
    posts = Post.objects.all()
    return render(request, '10/post_list.html', {'posts': posts})




from django.shortcuts import render, get_object_or_404, redirect
from .models import Post

def delete_post(request, post_id):
    post = get_object_or_404(Post, id=post_id)
    if request.method == 'POST':
        post.delete()
        return redirect('post_list')
    return render(request, '10/confirm_delete.html', {'post': post})

13.2 添加html代码

Test/templates/10/confirm_delete.html

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!-- templates/blog/confirm_delete.html -->
<form method="post">
    {% csrf_token %}
    <p>你确认要删除文章吗?</p>
    <button type="submit">确认</button>
</form>

</body>
</html>

13.3 添加路由地址

Test/app10/urls.py

复制代码
from django.contrib import admin
from django.urls import path
from app10 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('post_list', views.post_list, name='post_list'),
    path('delete_post/<int:post_id>/', views.delete_post, name='delete_post'),
]

13.4 访问页面

http://127.0.0.1:8000/app10/delete_post/2/

14,对比数据库数据

删除前

删除后

可以看到,我们通过post_id删除文章和关系表的数据,但是为什么标签表没有被删除呢?

在 Django 中,当你删除一个模型实例时,Django 会自动处理与该实例相关的多对多关系,但不会删除关联的标签。这是因为标签可能与其他文章也有关系,删除标签会影响其他数据的完整性。

  1. 多对多关系的管理:

    • 在 Django 中,多对多关系通过一个中间表来管理。当你删除一个 Post 实例时,Django 会自动删除中间表中与该 Post 实例相关的记录,但不会删除 Tag 表中的记录。
  2. 数据完整性:

    • 标签(Tag)通常是共享资源,可能被多个文章(Post)使用。如果删除某篇文章时也删除了标签,那么其他使用该标签的文章就会受到影响。因此,Django 默认不会删除标签。

Django admin后台及创建超级账号可参考:

Django 一对多关系-CSDN博客

相关推荐
言乐61 天前
HTML视频审核模型
python·django·virtualenv·pygame·tornado
言乐61 天前
Python根据无法识别搜索词找出可能输入内容模型
开发语言·python·django·virtualenv·pygame
yl45301 天前
硫酸泄露处理生产商怎么选才够专业
大数据·人工智能·python
笨笨饿1 天前
140_AI新手村MCP与Skills是干嘛的
开发语言·人工智能·python·stm32·单片机·嵌入式硬件·物联网
for_ever_love__1 天前
机器学习入门——手写线性回归与梯度下降
人工智能·python·学习·机器学习·线性回归
打工仔折腾 AI1 天前
从 Demo 到生产级 Agent:8 个关键设计机制与 Python 实现拆解
java·jvm·人工智能·后端·python·langchain·ai agent 实战
I Am a robert girl1 天前
当传感器学会“说谎“:拆解可靠性门控的稀疏惯性动捕融合
python·姿态估计·传感器融合·惯性动捕·imu传感器·可靠性门控·可穿戴计算
李航19831 天前
AI定制柜建模,需要详细的建模规范和标准流程
人工智能·python·计算机视觉·ai·ai编程
沙漠之主1 天前
Python 教学设计资料:从入门到实战的完整课程方案
爬虫·python
ebiobiz1 天前
极海 APM32 使用 Nimmake 编译指南
c++·python·单片机·嵌入式硬件·mcu