2011-12-27 17 views
7

Nie widzę różnicy w podklasowaniu obiektu models.manager i przesłonięcia metody get_query_set lub po prostu utworzeniu nowej metody w podklasie i zastosowaniu tej metody. Z tego powodu wziąłem przykład z książki django;modele podklasy. Menedżer

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

Dzięki temu mógłbym użyć; Person.women.all() lub Person.men.all(), aby pobrać cały obiekt modelu mężczyzn lub kobiet. Ale myślę, że podobną rzecz można osiągnąć bez przesłonięcia metody get_query_set po prostu robiąc;

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

Teraz, dzięki temu, mogę pobrać wszystkie te obiekty za pomocą trochę techniki; Person.objects.get_male() lub Person.objects.get_female(). Ale nie ma żadnej subtelnej różnicy między tym, jak mogę pobrać obiekty, ale istnieje różnica w zakresie czytelności i użycia w pierwszym przypadku, podczas gdy druga jest znacznie łatwiejsza do zrozumienia i ma mniejszy kod. Robią one znaczną różnicę w kodowaniu i wzory? Drugie z drugim, co jeśli umieszczę obie metody wewnątrz tej samej klasy;

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

Jeżeli wszystko co masz to 2 metody, organizacja dała mając zupełnie oddzielny menedżer nie jest warta - nie wiem, dlaczego książka Django byłoby zaproponować FemaleManager i MaleManager w przeciwieństwie do get_females i metod get_males na pojedynczym menedżerze. –

+1

To bardziej zależy od warstwy abstrakcji. Jeśli planujesz mieć 'PeopleManager', który po prostu oddziela ludzi według płci, druga opcja jest bardziej użyteczna. Jeśli w przyszłości na przykład 'FemaleManager' będzie miał metody takie jak' get_blondes() 'lub' get_married() 'to drugie podejście będzie bardziej odpowiednie. –

Odpowiedz

4
  1. Zwykle nie chcesz kilka menedżerów dla modelu. Lepiej przedłużyć domyślnego menedżera.

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

    Wtedy będziesz w stanie wykorzystać Person.objects.get_male(), Person.objects.get_female() i wbudowanych metod jak Person.objects.order_by(). Możesz na przykład spojrzeć na menedżerów niestandardowych pod numerem django.contrib.auth.models.

  2. get_query_set jest dobre dla dziedziczenia. Na przykład można zdefiniować

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

    i wszystkie metody zarządcy zwróci tylko Smiths (Person.objects.get_male() zwróci tylko samce nazwanych Smith i tak dalej). I nie trzeba przepisywać wszystkich metod.

+1

W tym przypadku, w twoim drugim punkcie, myślę, że to zależy od tego, jak utworzę obiekt wewnątrz mojego modelu. Jeśli założę, że robię obiekty = models.Manager() i osoba = SmithManager(). Wtedy mogę używać obiektów domyślnych i niestandardowego, który odziedziczyłem. – Sandeep

+1

@ insane-36 Czy jest jakiś dobry powód, aby nie przedłużać domyślnego menedżera? Kod z kilkoma menedżerami jest mniej jasny i trudniejszy do utrzymania. Dobra rada: zapomnij o menadżeście przez chwilę. Po prostu twórz widoki, formularze i inne rzeczy, używając zwykłych "obiektów". Następnie przeanalizuj użycie i stwórz jednego dobrego menedżera DRY, który rozwiąże * twoje zadania *. To będzie najlepszy menedżer. – DrTyrsa

+1

Dziękuję, ten temat był interesujący i dlatego poświęciłem chwilę na sprawdzenie tego. Teraz pójdę naprzód. – Sandeep