Subclassification of models.Manager

I see no difference in subclassing the models.manager object and overriding the get_query_set method or just creating a new method in a subclass and using the method. Due to the fact that I gave an example from the book of django,

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

With this I could use; Person.women.all() or Person.men.all() to retrieve all model objects for men or women. But, I think a similar thing can be achieved without overriding the get_query_set method simply:

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

Now, with this, I can get all these objects with a little technique; Person.objects.get_male() or Person.objects.get_female() . But there is no subtle difference between how I could get the objects, but in the first case there is a difference in exponentiality and use, while the second is much easier to understand and has less code. Do they make some significant differences in coding and patterns? Another thing with the second is that if I put both methods inside the same class, for example:

 class PeopleManager(models.Manager): def get_male(self): return self.filter(sex='M') def get_female(self): return return self.filter(sex='F') 
+7
source share
1 answer
  • Usually you do not need several managers for the model. Better extend the default manager.

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

    Then you can use Person.objects.get_male() , Person.objects.get_female() and built-in methods like Person.objects.order_by() . For example, you can see user managers at django.contrib.auth.models .

  • get_query_set is good for inheritance. For example, you can define

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

    and all manager methods will return only Smiths, ( Person.objects.get_male() will return only males named Smith, etc.). And you do not need to rewrite all the methods.

+4
source

All Articles