了解 Django ORM

Mary-Kate Olsen
发布: 2024-10-08 20:11:02
原创
353 人浏览过

Understanding Django ORM

什么是 ORM?

对象关系映射(ORM)是 Django 中的一项功能,它允许我们使用 Python 代码与数据库交互,而无需编写 SQL 查询。 ORM 在底层将 CRUD 操作转换为 SQL,从而可以轻松创建、检索、更新和删除数据库对象。

使用 ORM

在 Django 中,模型类代表数据库表,该类的实例代表表中的一条记录。

每个模型至少有一个Manager,称为对象。我们可以通过这个管理器从数据库中检索记录,从而产生一个 QuerySet

查询集是惰性的,这意味着在明确请求之前不会获取结果。

常用的 QuerySet 方法
filter():检索符合特定条件的记录。
all(): 检索所有记录。
order_by():根据特定字段对记录进行排序。
unique():返回唯一记录。
annotate():为每条记录添加聚合值。
aggregate():从查询集中计算一个值。
defer():仅加载模型的某些字段,推迟其他字段。

高级 ORM 功能

Q 和 F 对象 允许复杂的查询和高效的数据库级操作。对于涉及 OR 条件的查询,我们可以使用“Q”,而“F”则允许您在查询中直接引用模型字段。

from django.db.models import Q, F

# Using Q to filter published posts or created after a specific date
posts = Post.objects.filter(Q(status='published') | Q(created_at__gte='2024-01-01'))

# Using F to compare fields within a model (e.g., for a discount calculation)
class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    discounted_price = models.DecimalField(max_digits=10, decimal_places=2)

# Retrieve products where discounted price is less than price
discounted_products = Product.objects.filter(discounted_price__lt=F('price'))
登录后复制

查询表达式(引用模型字段)和数据库函数(应用类似SQL的函数)都允许我们在数据库级别执行操作,而不是将数据拉入Python进行处理。这有助于优化查询并减少数据库负载。

from django.db.models import Count, Max

# Count the number of posts for each status
status_count = Post.objects.values('status').annotate(count=Count('id'))

# Get the latest created post
latest_post = Post.objects.aggregate(latest=Max('created_at'))

登录后复制

自定义管理器让我们添加额外的管理器方法或修改管理器最初返回的查询集。

class PublishedManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(status='published')

class Post(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()
    status = models.CharField(max_length=50)
    created_at = models.DateTimeField(auto_now_add=True)

    objects = models.Manager()  # Default manager
    published = PublishedManager()  # Custom manager for published posts

# Use the custom manager to get published posts
published_posts = Post.published.all()

登录后复制

ContentType 是一个模型,可用于在模型之间创建通用关系,而无需使用直接外键指定它们。常见用例包括需要附加到不同类型模型的注释或标签。

from django.contrib.contenttypes.models import ContentType

# Example model for comments
class Comment(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')
    text = models.TextField()

# Creating a comment for a Post instance
post = Post.objects.get(id=1)
comment = Comment.objects.create(
    content_type=ContentType.objects.get_for_model(Post),
    object_id=post.id,
    text='Great post!'
)
登录后复制

事务将数据库操作捆绑为一个单元,确保数据一致性。我们可以使用 @transaction.atomic 装饰器或 transaction.atomic() 上下文管理器将代码包装在事务块中。

from django.db import transaction

# Using a transaction block
with transaction.atomic():
    post = Post.objects.create(title='New Post', content='Content here...', status='published')
    # Any other database operations will be part of this transaction
登录后复制

Django 允许在需要灵活性的情况下执行原始 SQL 查询 进行复杂查询。但需谨慎使用。

from django.db import connection

def get_published_posts():
    with connection.cursor() as cursor:
        cursor.execute("SELECT * FROM blog_post WHERE status = %s", ['published'])
        rows = cursor.fetchall()
    return rows
登录后复制

结论

Django 的 ORM 通过提供用于处理模型、管理器和查询的高级 API 来简化数据库交互。了解和利用这些功能可以极大地提高您的工作效率和应用程序的性能。

以上是了解 Django ORM的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!