djnago orm 一对多关系使用

在 Django 中,一对多关系通常通过外键(ForeignKey)来实现。以下是一个完整的示例,展示如何定义模型、创建一对多关系,并使用 Django ORM 进行连表查询。

1. 定义模型

假设我们有两个模型:AuthorBook一个作者可以有多本书,这就是一对多的关系

models.py
python 复制代码
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    email = models.EmailField()

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    publication_date = models.DateField()
    author = models.ForeignKey(Author, related_name='books', on_delete=models.CASCADE)

    def __str__(self):
        return self.title

2. 创建和应用迁移

在定义好模型后,需要创建和应用数据库迁移。

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

3. 创建一些示例数据

你可以使用 Django 管理后台或 Django shell 来创建一些示例数据。

使用 Django shell
bash 复制代码
python manage.py shell
python 复制代码
from myapp.models import Author, Book

# 创建作者
author1 = Author.objects.create(name="Author One", email="author1@example.com")
author2 = Author.objects.create(name="Author Two", email="author2@example.com")

# 创建书籍
Book.objects.create(title="Book One", publication_date="2023-01-01", author=author1)
Book.objects.create(title="Book Two", publication_date="2023-02-01", author=author1)
Book.objects.create(title="Book Three", publication_date="2023-03-01", author=author2)

4. 连表查询

现在可以使用 Django ORM 进行连表查询。

views.py
python 复制代码
from django.shortcuts import render
from myapp.models import Author, Book

def author_books(request, author_id):
    # 获取指定作者
    author = Author.objects.get(id=author_id)
    
    # 获取该作者的所有书籍
    books = author.books.all()
    
    return render(request, 'author_books.html', {'author': author, 'books': books})
urls.py
python 复制代码
from django.urls import path
from myapp import views

urlpatterns = [
    path('author/<int:author_id>/', views.author_books, name='author_books'),
]
author_books.html
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>Author Books</title>
</head>
<body>
    <h1>Books by {{ author.name }}</h1>
    <ul>
        {% for book in books %}
            <li>{{ book.title }} ({{ book.publication_date }})</li>
        {% endfor %}
    </ul>
</body>
</html>

5. 复杂查询示例

如果需要进行更复杂的查询,比如获取所有书籍及其对应的作者,可以使用 select_relatedprefetch_related

python 复制代码
def all_books(request):
    # 获取所有书籍及其对应的作者
    books = Book.objects.select_related('author').all()
    
    return render(request, 'all_books.html', {'books': books})
all_books.html
html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>All Books</title>
</head>
<body>
    <h1>All Books</h1>
    <ul>
        {% for book in books %}
            <li>{{ book.title }} by {{ book.author.name }} ({{ book.publication_date }})</li>
        {% endfor %}
    </ul>
</body>
</html>

6. 更新 urls.py

python 复制代码
urlpatterns = [
    path('author/<int:author_id>/', views.author_books, name='author_books'),
    path('books/', views.all_books, name='all_books'),
]
相关推荐
数据杂坛1 小时前
【Python程序开发系列】实例方法、类方法(@classmethod)、静态方法(@staticmethod)有什么区别
python·课程设计·python语法
正经教主2 小时前
【FDE系列】阶段2:Day 31:SQL 基础 — 增删改查一把梭
人工智能·python·fde
leihefeng2 小时前
PX04-用 Python 读 Excel 画折线图,还能直接插回 Excel 文件
python·excel
Mr.朱鹏2 小时前
Docker三剑客实战指南:Docker、Dockerfile 和 Docker Compose
python·docker·devops·dockerfile
0566462 小时前
用大模型构建答疑机器人:从 API 调用到上下文工程
python·学习·agent
haluhalu.2 小时前
初识 Protobuf:微服务跨语言通信的一份契约
java·c语言·开发语言·c++·python
Liaiyang662 小时前
# 自研 AST 容错初筛工具:横向评测 Django、PyTorch、TensorFlow 三大开源 Python 框架异常收容风险
python·测试工具·自动化·开源软件·代码规范·devops·代码复审
空奈qwq2 小时前
机器学习入门:从核心概念到建模全流程
人工智能·python·机器学习
IvanCodes2 小时前
Python 基础语法(六):字典与集合
python
lie..2 小时前
30天从零开始学AI应用开发(Day 4):Python 极速入门(上):够用就行,别啃书
人工智能·python·大模型