Django ORM功能如何实操?

访客 全栈框架 1

本文目录导读:

  1. 模型定义(建表)
  2. 创建记录(增)
  3. 查询记录(查)
  4. 更新记录(改)
  5. 删除记录(删)
  6. 高级查询
  7. 实操示例:图书管理系统
  8. 常见问题处理

Django ORM(对象关系映射)让你用Python代码操作数据库,而不需要直接写SQL,以下是核心实操指南:

模型定义(建表)

# models.py
from django.db import models
class Author(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntegerField()
    email = models.EmailField()
    created_at = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.name
class Book(models.Model):= models.CharField(max_length=200)
    price = models.DecimalField(max_digits=6, decimal_places=2)
    discount = models.FloatField(default=0.8)
    publish_date = models.DateField()
    available = models.BooleanField(default=True)
    author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
    def __str__(self):
        return self.title

创建记录(增)

# 方法1: 使用create()
author = Author.objects.create(name='张三', age=35, email='zhangsan@example.com')
# 方法2: 先实例化再save()
author = Author(name='李四', age=28)
author.save()
# 创建关联数据
book = Book.objects.create('Python入门', 
    price=59.90,
    author=author  # 传入author对象
)
# 或者使用author的related_name
book = author.books.create(title='Python进阶', price=79.90)

查询记录(查)

# 获取所有
all_authors = Author.objects.all()
# 获取单个(不存在则报错)
author = Author.objects.get(id=1)
# 条件查询
young_authors = Author.objects.filter(age__lt=30)  # 年龄小于30
active_books = Book.objects.filter(available=True)  # 可用的书
# 排除
adult_authors = Author.objects.exclude(age__lt=18)
# 链式查询
result = Book.objects.filter(price__gt=50).exclude(available=False)
# 排序
books_sorted = Book.objects.all().order_by('-price')  # 降序
books_sorted = Book.objects.all().order_by('publish_date')  # 升序
# 限制数量
first_3 = Book.objects.all()[:3]  # 前3条
one_skip = Book.objects.all()[1:2]  # 第2条
# 字段查询(常用)
Book.objects.filter(price__gt=30)    # 大于
Book.objects.filter(price__gte=30)   # 大于等于
Book.objects.filter(price__lt=100)   # 小于
Book.objects.filter(title__contains='Python')  # 包含
Book.objects.filter(title__startswith='Django') # 开头
Book.objects.filter(title__exact='Django入门')  # 精确匹配
Book.objects.filter(publish_date__year=2024)   # 年份

更新记录(改)

# 方法1: 获取后修改
book = Book.objects.get(id=1)
book.price = 69.90
book.save()
# 方法2: 批量更新
Book.objects.filter(available=True).update(price=89.90)
# 使用F表达式(字段运算)
from django.db.models import F
Book.objects.all().update(price=F('price') * F('discount'))

删除记录(删)

# 删除单个
book = Book.objects.get(id=1)
book.delete()
# 批量删除
Book.objects.filter(available=False).delete()
# 清空表
Book.objects.all().delete()

高级查询

from django.db.models import Count, Sum, Avg, Max, Min, Q
# 聚合查询
total_books = Book.objects.count()
avg_price = Book.objects.aggregate(Avg('price'))
max_price = Book.objects.aggregate(Max('price'))
# 分组统计
author_books = Author.objects.annotate(book_count=Count('books'))
for author in author_books:
    print(f"{author.name}: {author.book_count}本书")
# 复杂条件(OR)
from django.db.models import Q
books = Book.objects.filter(
    Q(price__lt=50) | Q(available=True)
)
# 关联查询(JOIN)
# 正向查询
book = Book.objects.get(id=1)
author_name = book.author.name  # 获取关联作者
# 反向查询
author = Author.objects.get(id=1)
all_books = author.books.all()  # 获取所有书籍(related_name='books')
# 预加载(减少查询次数)
from django.db.models import Prefetch
authors = Author.objects.prefetch_related('books').all()

实操示例:图书管理系统

# views.py
def book_list(request):
    # 复杂业务查询
    result = Book.objects.select_related('author').filter(
        available=True,
        price__gt=30
    ).order_by('-publish_date')[:10]
    # 统计信息
    stats = Book.objects.aggregate(
        total=Count('id'),
        avg_price=Avg('price'),
        min_price=Min('price')
    )
    return render(request, 'books.html', {
        'books': result,
        'stats': stats
    })

常见问题处理

# 处理get()不存在
from django.core.exceptions import ObjectDoesNotExist
try:
    book = Book.objects.get(id=999)
except ObjectDoesNotExist:
    book = None
# 使用get_object_or_404
from django.shortcuts import get_object_or_404
book = get_object_or_404(Book, id=1)
# 避免N+1查询
# 错误:每次循环都会查询数据库
authors = Author.objects.all()
for author in authors:
    print(author.books.count())  # N次查询
# 正确:使用annotate一次性查询
from django.db.models import Count
authors = Author.objects.annotate(book_count=Count('books'))
for author in authors:
    print(author.book_count)  # 1次查询

实操建议

  1. 先用python manage.py shell测试ORM操作
  2. 使用connection.queries查看实际SQL
  3. 复杂查询先写SQL再转ORM
  4. 善用select_relatedprefetch_related优化性能

标签: Django ORM 实操

抱歉,评论功能暂时关闭!