Django                
            Gestori e Queryys personalizzati
        
        
            
    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)vsUser.manager.active()
-  Ottieni tutti i dermatologi attivi sulla nostra piattaforma: User.objects.filter(is_active=True).filter(is_doctor=True).filter(specialization='Dermatology')vsUser.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. 
select_related per tutte le query
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')