Ricerca…


Definire un manager di base usando Querysets e il metodo `as_manager`

Django manger è un'interfaccia attraverso la quale il modello django interroga il database. Il campo degli objects usato nella maggior parte delle query di django è in realtà il gestore predefinito creato per noi da django (questo viene creato solo se non definiamo i gestori personalizzati).

Perché dovremmo definire un gestore personalizzato / queryset?

Per evitare di scrivere query comuni su tutto il nostro codebase e invece di riferirle usando un'astrazione più facile da ricordare. Esempio: decidi tu stesso quale versione è più leggibile:

  • Ottieni solo tutti gli utenti attivi: User.objects.filter(is_active=True) vs User.manager.active()
  • Ottieni tutti i dermatologi attivi sulla nostra piattaforma: User.objects.filter(is_active=True).filter(is_doctor=True).filter(specialization='Dermatology') vs User.manager.doctors.with_specialization('Dermatology')

Un altro vantaggio è che se domani decidiamo che tutti gli psychologists sono anche dermatologists , possiamo facilmente modificare la query nel nostro manager e farla finita.

Di seguito è riportato un esempio di creazione di un Manager personalizzato definito creando un QuerySet e utilizzando il metodo 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

Lo aggiungeremo al nostro modello come di seguito:

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

NOTA : una volta definito un manager sul nostro modello, gli objects non saranno più definiti per il modello.

Modello con ForeignKey

Lavoreremo con questi modelli:

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)

Supponiamo di accedere (sempre) spesso a book.author.name

In vista

Potremmo usare quanto segue, ogni volta,

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

Ma questo non è SECCO.

Manager personalizzato

class BookManager(models.Manager):

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

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

Nota : la chiamata a super deve essere cambiata per python 2.x

Ora tutto ciò che dobbiamo usare nelle viste è

books = Book.objects.all()

e nessuna query aggiuntiva sarà effettuata in template / view.

Definisci gestori personalizzati

Molto spesso capita di trattare con modelli che hanno qualcosa come un campo published . Questi tipi di campi sono quasi sempre usati per recuperare oggetti, così ti troverai a scrivere qualcosa come:

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

troppe volte. Puoi utilizzare i gestori personalizzati per gestire queste situazioni, in modo che tu possa scrivere qualcosa come:

my_news = News.objects.published()

che è più bello e più facile da leggere anche da altri sviluppatori.

Creare un file managers.py nella directory app, e definire una nuova models.Manager classe:

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)

usa questa classe ridefinendo la proprietà objects nella classe model:

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

Ora puoi ottenere le tue notizie pubblicate in questo modo:

my_news = News.objects.published()

e puoi anche eseguire più filtri:

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


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow