Модели подклассов. Менеджер - PullRequest
7 голосов
/ 27 декабря 2011

Я не вижу разницы в подклассе объекта models.manager и переопределении метода get_query_set или просто создании нового метода в подклассе и использовании метода.По этой причине я взял пример из книги Джанго:

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 Ответ

4 голосов
/ 27 декабря 2011
  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')
    

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...