2011-12-27 16 views
7

No veo ninguna diferencia al clasificar el objeto models.manager y anular el método get_query_set o simplemente crear un nuevo método en la clase secundaria y usar el método. Por la razón, he tomado el ejemplo del libro django;subclassing models.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 esto podría usar; Person.women.all() o Person.men.all() para buscar el objeto modelo de hombres o mujeres. Pero, supongo que se puede lograr algo similar sin anular el método get_query_set simplemente haciendo;

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

Ahora, con esto, puedo buscar todos esos objetos con un poco de técnica como; Person.objects.get_male() o Person.objects.get_female(). Pero no hay una diferencia sutil entre cómo puedo obtener los objetos, pero hay diferencia en términos de legibilidad y uso en el primer caso, mientras que el segundo es mucho más fácil de entender y tiene un código menor. ¿Tienen alguna diferencia significativa en la codificación y el patrones ? La otra cosa con el segundo, ¿y si coloco ambos métodos dentro de una misma clase como;

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

Si todo lo que tiene es 2 métodos, la organización ofrecida por tener un administrador completamente separados no vale la pena - no sé por qué el libro de Django sugeriría una FemaleManager y MaleManager en contraposición a un get_females y métodos get_males en un solo gerente. –

+1

Es más, depende de tu capa de abstracción. Si planeas tener 'PeopleManager' que simplemente separe las personas por género, la segunda opción es más útil. Si en el futuro, por ejemplo, 'FemaleManager' tendrá métodos como' get_blondes() 'o' get_married() ', entonces el segundo enfoque será más adecuado. –

Respuesta

4
  1. Por lo general, no quieren varios administradores para el modelo. Es mejor extender el administrador predeterminado.

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

    Entonces usted será capaz de utilizar Person.objects.get_male(), Person.objects.get_female() y métodos incorporados como Person.objects.order_by(). Puede ver administradores personalizados en django.contrib.auth.models por ejemplo.

  2. get_query_set es bueno para la herencia. Por ejemplo, puede definir

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

    y todos los métodos de la gerente devolverá sólo Smiths, (Person.objects.get_male() devolverá sólo los varones nombrados Smith y así sucesivamente). Y no necesita volver a escribir todos los métodos.

+1

En este caso, en su segundo punto supongo que depende de cómo instanciar el objeto dentro de mi modelo. Si supongo que hago objects = models.Manager(), y person = SmithManager(). Luego, puedo usar los objetos predeterminados y la costumbre que heredé. – Sandeep

+1

@ insana-36 ¿Hay alguna buena razón para no extender el administrador predeterminado? El código con varios gerentes es menos claro y más difícil de mantener. Un buen consejo: olvídate de los gerentes por un tiempo. Simplemente crea tus vistas, formularios y otras cosas, usando 'objetos' normales. Luego analiza el uso y crea un buen administrador DRY que resolverá * tus tareas *. Será el mejor gerente. – DrTyrsa

+1

Gracias, este tema fue interesante y por eso me tomé un tiempo para revisar esto. Voy a seguir adelante ahora. – Sandeep

Cuestiones relacionadas