2012-11-12 42 views
5

tôi có cấu trúc thừa kế mô hình sau đây trong Django:Django Lọc Base Class bởi trẻ em lớp Names

class Parent(models.Model): 
    # stuff 

class A(Parent): 
    # stuff 

class B(Parent): 
    # stuff 

class C(Parent): 
    # stuff 

and the list goes on. 

Tôi đang sử dụng InheritanceManager của django-mô hình-utils để lọc các đối tượng như:

Parent.objects.filter(foo=bar).select_subclasses() 

Điều này hoạt động tốt khi tôi muốn lọc tất cả các lớp con. Điều tôi muốn làm là lọc các đối tượng A và B chứ không phải đối tượng C. Tôi muốn thực hiện điều này với một truy vấn như

Parent.objects.filter(foo=bar, __class__.__name__=A, __class__.__name__=B).select_subclasses() 

Có thể thực hiện thao tác lọc như vậy và nếu có thể, hãy làm như thế nào?

+0

tại sao không chỉ làm 'A.objects.filter (foo = bar)' etc? –

+0

Tôi muốn lọc tất cả các đối tượng bằng một truy vấn, thay vì nhiều truy vấn –

Trả lời

0

Nó thường không được coi là tốt nhất để thiết lập kế thừa như vậy bởi vì sau đó mỗi truy vấn SQL sẽ phải làm một tham gia. Điều đó có thể làm cho hiệu suất của bạn chậm hơn nhiều. Để tăng hiệu suất, bạn có thể sử dụng giá trị abstract Meta:

class Parent(models.Model): 
    # stuff 
    class Meta: 
     abstract = True 

Bằng cách này mỗi bảng là độc lập và do đó hiệu suất sẽ nhanh hơn.

Nếu điều đó không áp dụng cho bạn, tôi không nghĩ có thể làm điều gì đó giống như vậy trong một truy vấn vì các trường trong bảng/mô hình không chứa bất kỳ thông tin nào trong bảng. Trong trường hợp đó, rất có thể bạn sẽ phải phân lớp bằng cách nào đó phân lớp là InheritanceManager tuy nhiên tôi không chắc chắn phải làm gì ở đó. Nếu bạn làm vậy, sử dụng content_types thì có thể có một số trợ giúp.

Nếu đó là quá nhiều công việc, sau đó bạn luôn có thể làm một hack đơn giản (nhiều hơn một con khỉ vá ...). Tôi biết mình không đẹp, nhưng nó sẽ làm việc:

class Parent(models.Model): 
    # stuff 
    table = models.CharField(max_length=8, default='parent') 

class A(Parent): 
    # stuff 
    table = models.CharField(max_length=8, default='a') 

class B(Parent): 
    # stuff 
    table = models.CharField(max_length=8, default='b') 


# and then something like 
# please note that I've never used django-model-utils 
# so don't know the correct syntax 
Parent.objects.filter(foo=bar, table__in=['parent', 'a']).select_subclasses() 
+0

Ok cảm ơn. Tôi không sử dụng một lớp cơ sở trừu tượng vì tôi muốn có khả năng lọc các đối tượng lớp cơ sở bằng cách sử dụng một truy vấn duy nhất thay vì sử dụng một truy vấn riêng biệt cho mỗi lớp con. Tôi chỉ muốn lọc một tập con của các lớp cơ sở ở một số nơi và một tập hợp con khác ở một nơi khác. Tôi sẽ đăng bài ở đây nếu tôi tìm thấy một giải pháp thỏa đáng –

0

Một giải pháp hacky đó là làm việc cho tôi, mà không cần bổ sung thêm thông tin cho cơ sở dữ liệu:

letters = Parent.objects.filter(foo=bar) 
for letter in letters: 
    if type(letter) == C: 
     letters.exclude(id=c.id) 

Hoặc cách khác, nếu bạn thêm thông tin vào mô hình mà không cần các lĩnh vực nói thêm:

class Parent(models.Model): 
    # stuff 

class A(Parent): 
    code = 'A' 
    # stuff 

class B(Parent): 
    code = 'B' 
    # stuff 

class C(Parent): 
    code = 'C' 
    # stuff 

Và sau đó ...

letters = Parent.objects.filter(foo=bar) 
for letter in letters: 
    if letter.child().code == 'C': 
     letters.exclude(id=c.id) 

Làm việc cho mục đích của tôi, mặc dù vẫn là một hack ...

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