ホームページ  >  記事  >  バックエンド開発  >  Django ORM を理解する

Django ORM を理解する

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-10-08 20:11:02355ブラウズ

Understanding Django ORM

ORMとは何ですか?

オブジェクト リレーショナル マッピング (ORM) は、SQL クエリを作成せずに Python コードを使用してデータベースと対話できるようにする Django の機能です。 ORM は CRUD 操作を内部で SQL に変換し、データベース オブジェクトの簡単な作成、取得、更新、削除を可能にします。

ORM の使用

Django では、モデル クラスはデータベース テーブルを表し、そのクラスのインスタンスはテーブル内のレコードを表します。

すべてのモデルには、オブジェクトと呼ばれるマネージャーが少なくとも 1 つあります。このマネージャーを通じてデータベースからレコードを取得すると、QuerySet が生成されます。

QuerySet は遅延型です。つまり、明示的に要求されるまで結果は取得されません。

一般的な QuerySet メソッド
filter(): 特定の基準に一致するレコードを取得します。
all(): すべてのレコードを取得します。
order_by(): 特定のフィールドに基づいてレコードを並べ替えます。
unique(): 一意のレコードを返します。
annotate(): 各レコードに集計値を追加します。
ggregate(): クエリセットから値を計算します。
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'))

カスタム マネージャー を使用すると、マネージャー メソッドを追加したり、マネージャーが最初に返す QuerySet を変更したりできます。

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。