Django 多对多关系

发布于:2024-07-03 ⋅ 阅读:(19) ⋅ 点赞:(0)

多对多关系作用

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博客