2011-12-27 21 views
7

Tôi thấy không có sự khác biệt trong phân lớp đối tượng models.manager và ghi đè phương thức get_query_set hoặc chỉ cần tạo phương thức mới trong lớp con và sử dụng phương thức. Vì lý do là tôi đã lấy ví dụ từ sách django;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() 

Với điều này tôi có thể sử dụng; Person.women.all() hoặc Person.men.all() để tìm nạp tất cả đối tượng người mẫu hoặc phụ nữ. Nhưng, tôi đoán điều tương tự có thể đạt được mà không cần ghi đè phương thức get_query_set đơn giản bằng cách thực hiện;

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

Bây giờ, với điều này, tôi có thể tìm nạp tất cả các đối tượng đó bằng một ít kỹ thuật như; Person.objects.get_male() hoặc Person.objects.get_female(). Tuy nhiên, không có bất kỳ sự khác biệt tinh tế nào giữa cách tôi có thể tìm nạp các đối tượng nhưng có sự khác biệt về khả năng đọc và sử dụng trong trường hợp đầu tiên trong khi trường hợp thứ hai dễ hiểu hơn và có mã ít hơn. mẫu? Một điều khác với cái thứ hai, nếu tôi đặt cả hai phương thức trong cùng một lớp như thế nào;

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

Nếu tất cả những gì bạn có là 2 phương pháp, tổ chức có được một người quản lý hoàn toàn riêng biệt không đáng phải lo lắng - không chắc chắn lý do tại sao sách django đề xuất Nữ quản lý và MaleManager như trái ngược với phương thức get_females và get_males trên một người quản lý. –

+1

Nó phụ thuộc nhiều hơn vào lớp trừu tượng của bạn. Nếu bạn có kế hoạch để có 'PeopleManager' mà chỉ tách người theo giới tính thứ hai tùy chọn hữu ích hơn. Nếu trong tương lai, ví dụ 'FemaleManager' sẽ có các phương thức như' get_blondes() 'hoặc' get_married() 'thì cách tiếp cận thứ hai phù hợp hơn. –

Trả lời

4
  1. Thông thường, bạn không muốn một vài nhà quản lý cho mô hình. Tốt hơn là mở rộng trình quản lý mặc định.

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

    Sau đó, bạn sẽ có thể sử dụng Person.objects.get_male(), Person.objects.get_female() và phương pháp tích hợp như Person.objects.order_by(). Bạn có thể xem xét các nhà quản lý tùy chỉnh trong ví dụ django.contrib.auth.models.

  2. get_query_set là tốt cho kế thừa. Ví dụ, bạn có thể định nghĩa

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

    và tất cả các phương pháp của người quản lý sẽ trở lại chỉ Smiths, (Person.objects.get_male() sẽ trở lại chỉ con đực tên là Smith và vân vân). Và bạn không cần viết lại tất cả các phương thức.

+1

Trong trường hợp này, ở điểm thứ hai của bạn, tôi đoán nó phụ thuộc vào cách tôi khởi tạo đối tượng bên trong mô hình của mình. Nếu giả sử tôi làm đối tượng = models.Manager(), và person = SmithManager(). Sau đó, tôi có thể sử dụng các đối tượng mặc định và tùy chỉnh mà tôi đã kế thừa. – Sandeep

+1

@ insane-36 Bất kỳ lý do nào tốt không chỉ mở rộng trình quản lý mặc định? Mã với một số nhà quản lý ít rõ ràng và khó bảo trì hơn. Lời khuyên tốt: quên đi các nhà quản lý trong một thời gian. Chỉ cần tạo các khung nhìn, biểu mẫu, các thứ khác của bạn, sử dụng các đối tượng 'bình thường'. Sau đó phân tích việc sử dụng và tạo một trình quản lý DRY ​​tốt để giải quyết * các tác vụ của bạn *. Nó sẽ là người quản lý tốt nhất. – DrTyrsa

+1

Cảm ơn, chủ đề này thật thú vị và tôi đã dành một chút thời gian để xem lại điều này. Tôi sẽ đi trước. – Sandeep

Các vấn đề liên quan