Recherche…


Définition d'un gestionnaire de base à l'aide de la méthode Querysets et de la méthode `as_manager`

Django manger est une interface par laquelle le modèle django interroge la base de données. Le champ d' objects utilisé dans la plupart des requêtes django est en fait le gestionnaire par défaut créé par django (il est créé uniquement si nous ne définissons pas de gestionnaires personnalisés).

Pourquoi définirions-nous un gestionnaire / groupe de requête personnalisé?

Pour éviter d'écrire des requêtes communes sur notre base de code et de les renvoyer à l'aide d'une abstraction plus facile à retenir. Exemple: Décidez pour vous-même quelle version est la plus lisible:

  • User.objects.filter(is_active=True) que tous les utilisateurs actifs: User.objects.filter(is_active=True) vs User.manager.active()
  • Obtenez tous les dermatologues actifs sur notre plateforme: User.objects.filter(is_active=True).filter(is_doctor=True).filter(specialization='Dermatology') vs User.manager.doctors.with_specialization('Dermatology')

Un autre avantage est que si demain nous décidons que tous les psychologists sont aussi des dermatologists , nous pouvons facilement modifier la requête dans notre gestionnaire et en finir avec elle.

Vous trouverez ci-dessous un exemple de création d'un Manager personnalisé défini en créant un QuerySet et en utilisant la méthode as_manager .

from django.db.models.query import QuerySet

class ProfileQuerySet(QuerySet):
    def doctors(self):
        return self.filter(user_type="Doctor", user__is_active=True)

    def with_specializations(self, specialization):
        return self.filter(specializations=specialization)

    def users(self):
        return self.filter(user_type="Customer", user__is_active=True)

ProfileManager = ProfileQuerySet.as_manager

Nous allons l'ajouter à notre modèle comme ci-dessous:

class Profile(models.Model):
    ...
    manager = ProfileManager()

REMARQUE : Une fois que nous avons défini un manager sur notre modèle, les objects ne seront plus définis pour le modèle.

Modèle avec ForeignKey

Nous allons travailler avec ces modèles:

from django.db import models

class Book(models.Model):
 name= models.CharField(max_length=50)
 author = models.ForeignKey(Author)

class Author(models.Model):
 name = models.CharField(max_length=50)

Supposons que nous book.author.name souvent (toujours) à book.author.name

En vue

Nous pourrions utiliser ce qui suit à chaque fois

books = Book.objects.select_related('author').all()

Mais ce n'est pas sec.

Gestionnaire personnalisé

class BookManager(models.Manager):

    def get_queryset(self):
        qs = super().get_queryset()
        return qs.select_related('author')

class Book(models.Model):
    ...
    objects = BookManager()

Note : l'appel à super doit être changé pour python 2.x

Maintenant, tout ce que nous devons utiliser dans les vues est

books = Book.objects.all()

et aucune requête supplémentaire ne sera faite dans un modèle / vue.

Définir des gestionnaires personnalisés

Très souvent, il s'agit de modèles qui ont quelque chose comme un champ published . Ces types de champs sont presque toujours utilisés lors de la récupération d'objets, de sorte que vous vous retrouvez à écrire quelque chose comme:

my_news = News.objects.filter(published=True)

trop de fois. Vous pouvez utiliser des gestionnaires personnalisés pour gérer ces situations, de sorte que vous puissiez ensuite écrire quelque chose comme:

my_news = News.objects.published()

ce qui est plus agréable et plus facile à lire par les autres développeurs.

Créez un fichier managers.py dans votre répertoire d'application et définissez une nouvelle classe models.Manager :

from django.db import models


class NewsManager(models.Manager):

    def published(self, **kwargs):
        # the method accepts **kwargs, so that it is possible to filter
        # published news
        # i.e: News.objects.published(insertion_date__gte=datetime.now)
        return self.filter(published=True, **kwargs)

utilisez cette classe en redéfinissant la propriété objects dans la classe de modèle:

from django.db import models

# import the created manager
from .managers import NewsManager

class News(models.Model):
    """ News model
    """
    insertion_date = models.DateTimeField('insertion date', auto_now_add=True)
    title = models.CharField('title', max_length=255)
    # some other fields here
    published = models.BooleanField('published')

    # assign the manager class to the objects property
    objects = NewsManager()

Maintenant, vous pouvez obtenir vos nouvelles publiées simplement de cette manière:

my_news = News.objects.published()

et vous pouvez également effectuer plus de filtrage:

my_news = News.objects.published(title__icontains='meow')


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow