Comprendre Django ORM

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-10-08 20:11:02502parcourir

Understanding Django ORM

Qu’est-ce que l’ORM ?

Le mappage objet-relationnel (ORM) est une fonctionnalité de Django qui nous permet d'interagir avec des bases de données en utilisant du code Python sans écrire de requêtes SQL. L'ORM traduit les opérations CRUD en SQL sous le capot, permettant ainsi une création, une récupération, une mise à jour et une suppression faciles d'objets de base de données.

Travailler avec ORM

Dans Django, une classe modèle représente une table de base de données et une instance de cette classe représente un enregistrement dans la table.

Chaque modèle a au moins un Manager, appelé objets. Nous pouvons récupérer des enregistrements de la base de données via ce gestionnaire, ce qui donne un QuerySet.

Les QuerySets sont paresseux, ce qui signifie que les résultats ne sont récupérés que lorsqu'ils sont explicitement demandés.

Méthodes QuerySet courantes
filter() : Récupère les enregistrements correspondant à certains critères.
all() : Récupère tous les enregistrements.
order_by() : commande les enregistrements en fonction de champs spécifiques.
distinct() : renvoie des enregistrements uniques.
annotate() : ajoutez des valeurs globales à chaque enregistrement.
Aggregate() : Calcule une valeur à partir d'un ensemble de requêtes.
defer() : Charger uniquement certains champs d'un modèle, en différant les autres.

Fonctionnalités ORM avancées

Les

Objets Q et F permettent des requêtes complexes et des opérations efficaces au niveau de la base de données. Nous pouvons utiliser « Q » pour les requêtes qui impliquent des conditions OU, tandis que « F » vous permet de référencer les champs du modèle directement dans les requêtes.

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'))
Les

Expressions de requête (référençant les champs du modèle) et les Fonctions de base de données (appliquant des fonctions de type SQL) nous permettent toutes deux d'effectuer des opérations au niveau de la base de données au lieu d'extraire des données dans Python pour les traiter. . Cela permet d'optimiser les requêtes et de réduire la charge de la base de données.

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'))

Gestionnaires personnalisés ajoutons des méthodes de gestionnaire supplémentaires ou modifions le QuerySet que le gestionnaire renvoie initialement.

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 est un modèle utile pour créer des relations génériques entre modèles sans les spécifier avec des clés étrangères directes. Les cas d'utilisation courants incluent des commentaires ou des balises qui doivent être attachés à différents types de modèles.

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!'
)
Les

Transactions regroupent les opérations de base de données en une seule unité garantissant la cohérence des données. Nous pouvons utiliser le décorateur @transaction.atomic ou le gestionnaire de contexte transaction.atomic() pour envelopper le code dans un bloc de transaction.

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 permet d'exécuter des requêtes SQL brutes pour des requêtes complexes où vous avez besoin de flexibilité. Cependant, il doit être utilisé avec prudence.

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

Conclusion

L'ORM de Django simplifie les interactions avec les bases de données en fournissant une API de haut niveau pour travailler avec des modèles, des gestionnaires et des requêtes. Comprendre et utiliser ces fonctionnalités peut considérablement améliorer votre productivité et les performances de vos applications.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn