Django custom model managers

断了今生、忘了曾经 提交于 2019-12-20 10:00:14

问题


I'm confused about the correct way to use Django custom model managers - based on the docs you can create a series of managers for one model as a way of filtering. But why not create one manager class with a series of functions for filtering? Is one method better than the other? and why?

For example:

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

versus

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

回答1:


With first method you can write:

men = Person.men.all()

or

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

For the second one method get_query_set is 'inherit' from model, then it return query set without customization. I don't know any reason to discard your second method, if you are using Admin interface you should check that this is suported.

Also, for the second one method you should correct your question. Is

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

Read django manager doc: "You can override a Manager's base QuerySet by overriding the Manager.get_query_set() method. get_query_set() should return a QuerySet with the properties you require."

Edited 2017 Be careful, get_query_set is renamed from djanto 1.7 to get_queryset. More info at Modifying a manager’s initial QuerySet



来源:https://stackoverflow.com/questions/8115009/django-custom-model-managers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!