2011-12-27 8 views
7

Я не вижу различий в подклассе класса models.manager и переопределяя метод get_query_set или просто создавая новый метод в подклассе и используя этот метод. По той причине, что я взял пример из книги джанго;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() 

С этим я мог бы воспользоваться; Person.women.all() или Person.men.all(), чтобы получить все модели модели для мужчин или женщин. Но, я думаю, подобная вещь может быть достигнута без переопределения метода get_query_set, просто делая;

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

Теперь, с этим, я могу получить все эти объекты с небольшой техникой; Person.objects.get_male() или Person.objects.get_female(). Но нет никакой тонкой разницы между тем, как я мог бы получить объекты, но в первом случае есть разница с точки зрения удобочитаемости и использования, в то время как вторая намного легче понять и имеет меньший код. Они делают некоторые существенные различия в кодировании и шаблоны? Другое дело со вторым, что, если я положу оба метода внутри одного класса;

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

Если все у вас есть 2 способа, организации, обеспечиваемая имея совершенно отдельный менеджер не стоит свеч - не знаю, почему Джанго книга будет предложить FemaleManager и MaleManager в отличие от get_females и методов get_males на одного менеджера. –

+1

Это больше зависит от вашего уровня абстракции. Если вы планируете иметь «PeopleManager», который просто отделяет людей по полу, второй вариант более полезен. Если в будущем, например, 'FemaleManager' будет иметь методы типа' get_blondes() 'или' get_married() ', тогда второй подход более подходит. –

ответ

4
  1. Обычно вы не хотите несколько менеджеров для модели. Лучше расширить менеджер по умолчанию.

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

    Тогда вы будете иметь возможность использовать Person.objects.get_male(), Person.objects.get_female() и встроенные методы, как Person.objects.order_by(). Например, вы можете посмотреть пользовательские менеджеры в django.contrib.auth.models.

  2. get_query_set подходит для наследства. Например, вы можете определить

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

    и все методы менеджера будут возвращать только Smiths (Person.objects.get_male() будет возвращать только мужчина по имени Смита и так далее). И вам не нужно переписывать все методы.

+1

В этом случае, во второй точке, я думаю, это зависит от того, как я создаю объект внутри своей модели. Если предположим, что я делаю объекты = models.Manager() и person = SmithManager(). Затем я могу использовать объекты по умолчанию и пользовательский стиль, который я унаследовал. – Sandeep

+1

@ insane-36 Любая хорошая причина не просто расширять менеджер по умолчанию? Код с несколькими менеджерами менее ясен и сложнее поддерживать. Хороший совет: забудьте о менеджерах на некоторое время. Просто создайте свои представления, формы и прочее, используя обычные «объекты». Затем проанализируйте использование и создайте одного хорошего менеджера DRY, который решит * ваши задачи *. Это будет лучший менеджер. – DrTyrsa

+1

Спасибо, эта тема была интересной, и поэтому я потратил некоторое время на это. Я пойду вперед. – Sandeep

Смежные вопросы