2011-11-13 17 views
12

Tôi nhầm lẫn về cách sử dụng đúng trình quản lý mô hình tùy chỉnh Django - dựa trên tài liệu bạn có thể tạo một chuỗi các nhà quản lý cho một mô hình như một cách lọc. Nhưng tại sao không tạo ra một lớp quản lý với một loạt các chức năng để lọc? Là một phương pháp tốt hơn so với phương pháp khác? và tại sao?Trình quản lý mô hình tùy chỉnh Django

Ví dụ:

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

so

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 

Trả lời

12

Với phương pháp đầu tiên bạn có thể viết:

men = Person.men.all() 

hoặc

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

Đối với phương thức thứ hai get_query_set là 'kế thừa' từ mô hình, sau đó nó trả về bộ truy vấn mà không cần tùy chỉnh. Tôi không biết bất kỳ lý do gì để loại bỏ phương pháp thứ hai của bạn, nếu bạn đang sử dụng giao diện Admin, bạn nên kiểm tra xem điều này có được hỗ trợ hay không.

Ngoài ra, đối với phương pháp thứ hai, bạn nên sửa câu hỏi của mình. Là

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

Read django manager doc: "Bạn có thể ghi đè lên QuerySet cơ sở của một quản lý bằng cách ghi đè các phương pháp Manager.get_query_set() get_query_set() sẽ trả về một QuerySet với các thuộc tính bạn yêu cầu.."

Đã chỉnh sửa năm 2017 Hãy cẩn thận, get_query_set được đổi tên từ djanto 1.7 thành get_queryset. Thông tin thêm tại Modifying a manager’s initial QuerySet

+1

Có nhưng hai phương pháp đang trả về querysets ... vì vậy sẽ không Person.objects.females.filter (first_name = 'Jane') vẫn hoạt động? ... –

+1

@ 9-bit: Đừng quên thực sự gọi phương thức. –

+0

@ IgnacioVazquez-Abrams ý của bạn là gì? Sẽ không Person.people.females.filter (first_name = 'Jane') gọi phương pháp sau đó lọc? –