2011-11-13 14 views
12

Estoy confundido acerca de la forma correcta de usar gestores de modelos personalizados de Django: en base a los documentos, puede crear una serie de gerentes para un modelo como una forma de filtrar. ¿Pero por qué no crear una clase de administrador con una serie de funciones para filtrar? ¿Un método es mejor que el otro? ¿y por qué?Gerentes de modelos personalizados de Django

Por ejemplo:

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

frente

class PersonManager(models.Manager): 
    def males(self): 
     return super(MaleManager, self).get_query_set().filter(sex='M') 

    def females(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 = PersonManager() 

Person.people.females() # to get list of females 
Person.people.males() # to get a list of males 

Respuesta

12

Con el primer método se puede escribir:

men = Person.men.all() 

o

peters_men = Person.men.filter(first_name='Peter') 

Para el segundo método get_query_set es 'inherit' del modelo, luego devuelve conjunto de consultas sin personalización. No conozco ninguna razón para descartar su segundo método. Si usa la interfaz de administración, debe verificar que esto sea compatible.

Además, para el segundo método, debe corregir su pregunta. Es

class PersonManager(models.Manager): 
    def males(self): 
     return super(PersonManager, self).get_query_set().filter(sex='M') 

Read django manager doc: "Puede anular QuerySet la base de un Gerente reemplazando el método Manager.get_query_set() get_query_set() debe devolver un QuerySet con las propiedades que se requieren.".

Editado 2017 Tenga cuidado, get_query_set se renombra de djanto 1.7 a get_queryset. Más información en Modifying a manager’s initial QuerySet

+1

Sí, pero los dos métodos son retornar querysets ... ¿así que no funcionaría Person.objects.females.filter (first_name = 'Jane')? ... –

+1

@ 9 bits: no olvides llamar realmente al método. –

+0

@ IgnacioVazquez-Abrams ¿qué quieres decir? ¿No llamaría Person.people.females.filter (first_name = 'Jane') al método y luego filtrar? –

Cuestiones relacionadas