2012-11-12 28 views
5

Ben Django aşağıdaki model devralma yapısı:Django Çocuk Sınıf Names temel sınıf Filtre

class Parent(models.Model): 
    # stuff 

class A(Parent): 
    # stuff 

class B(Parent): 
    # stuff 

class C(Parent): 
    # stuff 

and the list goes on. 

Gibi nesneleri filtre django-model Araçlarının InheritanceManager kullanıyorum:

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

Tüm alt sınıfları filtrelemek istediğimde bu iyi çalışıyor. Yapmak istediğim, A ve B nesnelerini filtrelemek, ancak C nesnelerini değil. Ben

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

böyle bir filtreleme işlemi yapmak mümkün mü ve nasıl mümkünse Tek bir sorgu ile yapmak istiyor gibi mi?

+0

neden sadece yapmak 'A. obje.filter (foo = bar)' vb? –

+0

Tüm nesneler tek bir sorgu ile filtrelemek istiyorum, birden çok sorgu yerine –

cevap

0

Genellikle, her bir SQL sorgusu bir katılma yapmak zorunda olduğu için bunun gibi kalıtımsal olarak en iyi şekilde ayarlanmış sayılmaz. Bu, performansınızı çok daha yavaş hale getirebilir.

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

her tablo bağımsız ve dolayısıyla performansı daha hızlı olacaktır Bu şekilde: performansı artırmak için, abstract Meta değerini kullanabilirsiniz.

Bu sizin için geçerli değilse, tek bir sorguda bunun gibi bir şey yapmanın mümkün olduğunu düşünmüyorum çünkü tablo/model içindeki alanlar hangi tabloda yer aldıklarını içermiyor. Bu durumda, muhtemelen bir şekilde InheritanceManager alt sınıfını yapmanız gerekecektir, ancak orada ne yapacağımı bilmiyorum. Bunu yaparsanız, content_types kullanarak bazı yardımlar olabilir.

Bu çok fazla iş varsa, o zaman her zaman basit bir kesmek yapabilirsiniz (daha fazla maymun yama ...). Ben onun güzel değil biliyorum ama işe yarayacak:

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 teşekkürler. Her bir alt sınıf için ayrı bir sorgu kullanmak yerine, tek bir sorgu kullanarak temel sınıf nesnelerini filtrelemeyi istediğimden soyut bir temel sınıf kullanmadım. Bazı yerlerde temel sınıfların bir alt kümesini ve başka bir alt kümeyi başka bir yere filtrelemek istedim. Tatmin edici bir çözüm bulursam gönderirim –

0

benim için çalışmış bir diğer hacky çözüm, veritabanına bilgi eklemeden: alternatif

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

Ya da, bilgi eklemek eğer eklemeden alanlar olmadan modeller: o zaman

class Parent(models.Model): 
    # stuff 

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

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

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

Ve ...

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

Yine de bir hack olsa da, benim amaçları için çalışır ...

İlgili konular