2011-12-27 16 views
7

Non vedo alcuna differenza nella sottoclassificazione dell'oggetto models.manager e sovrascrivendo il metodo get_query_set o semplicemente creando un nuovo metodo nella sottoclasse e utilizzando il metodo. Per la ragione di aver preso esempio dal libro di Django;.Manager

class MaleManager(models.Manager): 
    def get_query_set(self): 
     return super(MaleManager, self).get_query_set().filter(sex='M') 
class FemaleManager(models.Manager): 
    def get_query_set(self): 
     return super(FemaleManager, self).get_query_set().filter(sex='F') 
class Person(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female'))) 
    people = models.Manager() 
    men = MaleManager() 
    women = FemaleManager() 

Con questo potrei usare; Person.women.all() o Person.men.all() per recuperare tutti gli oggetti del modello maschile o femminile. Ma, immagino che la cosa simile possa essere ottenuta senza sovrascrivere il metodo get_query_set semplicemente facendo;

class MaleManager(models.Manager): 
    def get_male(self): 
     return self.filter(sex='M') 
class FemaleManager(models.Manager): 
    def get_female(self): 
     return return self.filter(sex='F') 
class Person(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female'))) 
    people = models.Manager() 
    men = MaleManager() 
    women = FemaleManager() 

Ora, con questo, posso recuperare tutti quegli oggetti con una piccola tecnica come; Person.objects.get_male() o Person.objects.get_female(). Ma non c'è alcuna sottile differenza tra il modo in cui posso recuperare gli oggetti, ma c'è una differenza in termini di leggibilità e uso nel primo caso mentre il secondo è molto più facile da capire e ha un codice minore. Fanno alcune differenze significative nella codifica e modelli? L'altra cosa con la seconda, cosa succede se metto entrambi i metodi all'interno di una stessa classe come;

class PeopleManager(models.Manager): 
     def get_male(self): 
      return self.filter(sex='M') 
     def get_female(self): 
      return return self.filter(sex='F') 
+1

Se hai a disposizione solo 2 metodi, l'organizzazione offerta da avere un manager completamente separata non vale la pena - non so perché il libro Django suggerirebbe un FemaleManager e MaleManager al contrario di un get_females e metodi get_males su un singolo manager. –

+1

Dipende più dal tuo livello di astrazione. Se stai pianificando di avere 'PeopleManager' che separa le persone per genere seconda opzione più utile. Se in futuro, ad esempio, 'FemaleManager' avrà metodi come' get_blondes() 'o' get_married() ', il secondo approccio sarà più adatto. –

risposta

4
  1. Di solito non si vuole alcuni manager per il modello. È meglio estendere il gestore predefinito.

    class PeopleManager(models.Manager): 
        def get_male(self): 
         return self.filter(sex='M') 
    
        def get_female(self): 
         return return self.filter(sex='F') 
    
    class Person(models.Model): 
        .... 
        objects = PeopleManager() 
    

    Allora si sarà in grado di utilizzare Person.objects.get_male(), Person.objects.get_female() e metodi built-in come Person.objects.order_by(). Ad esempio, puoi guardare i gestori personalizzati in django.contrib.auth.models.

  2. get_query_set è buono per l'ereditarietà. Per esempio è possibile definire

    class SmithManager(PeopleManager): 
        def get_queryset(self): 
         return super(SmithManager, self).get_query_set().filter(last_name='Smith') 
    

    e tutti i metodi del manager tornerà solo Smiths, (Person.objects.get_male() restituirà solo i maschi di nome Smith e così via). E non è necessario riscrivere tutti i metodi.

+1

In questo caso, nel tuo secondo punto credo dipenda da come istanziato l'oggetto all'interno del mio modello. Se supponiamo che faccio object = models.Manager() e person = SmithManager(). Quindi, sono in grado di utilizzare gli oggetti predefiniti e l'abitudine che ho ereditato. – Sandeep

+1

@ insane-36 Qualche buona ragione per non estendere semplicemente il gestore predefinito? Il codice con diversi gestori è meno chiaro e difficile da mantenere. Un buon consiglio: dimentica i gestori per un po '. Crea semplicemente viste, moduli, altre cose, usando normali 'oggetti'. Quindi analizza l'utilizzo e crea un buon DRY manager che risolva * i tuoi compiti *. Sarà il miglior manager. – DrTyrsa

+1

Grazie, questo argomento è stato interessante e quindi ho impiegato un po 'di tempo per riesaminarlo. Andrò avanti ora. – Sandeep