2011-04-16 27 views
27

Django model sınıfımda yerleşik bir işlev var ve bu işlevi sorgu sonuçlarıma filtre uygulamak için kullanmak istiyorum.Django: Özel işlevine göre filtre sorgusu

class service: 
     ...... 
     def is_active(self): 
      if datetime.now() > self.end_time: 
        return False 
      return True 

Şimdi ben biliyorum

nserv = service.objects.filter(is_active=True) 

gibi benim sorgu filtresi, bir şey içine bu fonksiyonu kullanmak istiyorum, bu basit 'is_active' durum için, doğrudan filtre sorguda bu Karşılaştırma yapabilmek, ancak Daha karmaşık durumlar için, bu mümkün olmayabilir. Özel işlevlere göre nasıl bir sorgu oluşturmalıyım?

+3

, sen 'yapabileceğini) (datetime.now dönmek <= self.end_time' – Rikki

+0

:-) ben tam olarak aynı problem vardı! Fonksiyon aynı bile çağrıldı –

cevap

17

böyle kullanmak olabilir, sınıfınız için özel bir yöneticisi kullanmanızı öneririm: Örneğin

gibi:

class ServiceManager(models.Manager): 
    def are_active(self): 
     # use your method to filter results 
     return you_custom_queryset 

Bkz. custom managers

+20

'# sonuçları filtrelemek için yönteminizi kullanın 'sorusunun ne olduğunu sormak oldukça fazladır yap. –

+0

@Ignacio - Aslında bu çözüm bana da yakışıyor. Bu yüzden sadece farklı bir şeyler denemek uğruna gideceğim. – Neo

16

Bunun yerine, queryset'i list comprehension veya generator expression ile işlemden geçirebilirsiniz.

nserv = service.objects.are_active()

Bu şeyle elde edilebilir olacaktır:

[x for x in Q if x.somecond()] 
+3

LC/genex nedir? – Neo

+6

LC = [okuduğunu anlama] (http://docs.python.org/tutorial/datastructures.html#list-comprehensions). genex = [generator expression] (http://docs.python.org/reference/expressions.html#generator-expressions) –

+0

@A lee -: P hala python lingo'da hız kazanmadım. – Neo

13

Benzer bir sorunla karşılaştım. Sorun, bir QuerySet örneğini döndürmem gerektiğiydi. Benim için hızlı bir çözüm böyle bir şey yapmak vardı:

active_serv_ids = [service.id for service in Service.objects.all() if service.is_active()] 
nserv = Service.objects.filter(id__in=active_serv_ids) 

bu bunu yapmak için güzel ve ölçülebilir şekilde değil, ama ben benim için çalışıyor oldukça emin.

Bunu yapmanın daha ayrıntılı şekilde olacaktır:

active_serv_ids = [] 

for service in Service.objects.all(): 
if service.is_active(): 
    active_serv_ids.append(service.id) 

nserv = Service.objects.filter(id__in=active_serv_ids) 
+0

Teşekkür ederim bu mükemmel. Bu "sonuçları yüklemek" ve istemci tarafında filtreleme yapmak için henüz bir django özelliği değildir, bu yüzden tek yol budur. – beiller

4

Ignacio tarafından cevap ilginçtir, ama bir Sorgu Kümesi döndürmez. Ama bu yapıyor: Bu arada

def users_by_role(role): 
    users = User.objects.all() 
    ids = [user.id for user in users if user.role == role] 
    return users.filter(id__in=ids)