2013-05-11 22 views
6

Ben şuna benzer bir Django modele sahip değerlerini karşılaştırmak kodlayıcı için 4. Yapabildiğim şey, kodlayıcı 3 ile kodlayıcı 4 arasındaki değerdeki farkın 1'den büyük olduğu tüm Yanıt nesnelerinin bir listesini almaktır. Değer alanı 1-7 numaralarını saklar.Django iki nesne

Bir Charfield olarak değer kurma bir hata olmuş olabilir Gez farkındayım ama umarım bunu sorunun üstesinden gelebilirsiniz.

aşağıdaki SQL gibi bir şey aradığım ne yapardın inanıyoruz, ancak sorguda zaten bir tabloya katıldığınızda Daha doğrusu ORM

SELECT UNIQUE c1.response_id FROM coding c1, coding c2 
WHERE c1.coder_id = 3 AND 
     c2.coder_id = 4 AND 
     c1.qid = "risk" AND 
     c2.qid = "risk" AND 
     c1.response_id = c2.response_id AND 
     c1.value - c2.value > 1 
+1

Sana Sorgunuzun WHERE cümleciği 'c1.response_id = c2.response_id' kapsar düşünüyorum. –

+0

@AryehLeibTaurog evet yaptım. Teşekkürler. – Ryan

cevap

2
from django.db.models import F 
qset = Coding.objects.filter(response__coding__value__gt=F('value') + 1, 
          qid='risk', coder=4 
        ).extra(where=['T3.qid = %s', 'T3.coder_id = %s'], 
          params=['risk', 3]) 
responses = [c.response for c in qset.select_related('response')] 

ile bu yapardım , ORM, extra() parametrelerini kullanarak kullanabileceğiniz, bu durumda T3, ikinci bir takma ad atacaktır. Takma adın ne olduğunu öğrenmek için kabuğa ve print qset.query'a girebilirsiniz.

Bkz Django F objects üzerine dokümantasyon ve extra

Güncelleme: Her zaman sizin aramalarını response__coding bakın çünkü aslında, extra() kullanın veya takma kullanımlarını django anlamaya gerek yok gibi görünüyor, django başlangıçta oluşturulan diğer adı kullanacaktır. İşte her iki yönde farklılıklara bakmak bir yolu: BTW Q objects

üzerinde

from django.db.models import Q, F 
gt = Q(response__coding__value__gt=F('value') + 1) 
lt = Q(response__coding__value__lt=F('value') - 1) 
match = Q(response__coding__qid='risk', response__coding__coder=4) 
qset = Coding.objects.filter(match & (gt | lt), qid='risk', coder=3) 
responses = [c.response for c in qset.select_related('response')] 

Bkz Django belgeleri her iki Kodlama örneklerini istemek yapacaksanız, size, çünkü burada bir N + 1 sorgular sorun var django'nun select_related() ters FK ilişkilerini almayacaktır. Ancak, zaten sorgudaki verilere sahip olduğunuzdan, yukarıda açıklanan T3 takma adlarını ve extra(select={'other_value':'T3.value'})'u kullanarak gerekli bilgileri alabilirsiniz. Karşılık gelen Kodlama kaydındaki value verisine, alınan Kodlama örneğindeki bir öznitelik, yani c.other_value olarak erişilebilir.

arada, sorunuz yeterince geneldir, ancak bir RDB senaryosunda genellikle bir anti-desen kabul edilir bir varlık-nitelik değeri şema, varmış gibi görünüyor. Bir risk alanıyla Sen daha iyi uzun vadeli olabilir (ve bu sorgu daha basit olurdu):

class Coding(models.Model): 
    response = models.ForeignKey(Response) 
    coder = models.ForeignKey(User) 
    risk = models.IntegerField() 
    # other fields for other qid 'attribute' names... 
+0

Bu harika. Kodlayıcı 3 veya kodlayıcı 4'ün daha yüksek olup olmadığına bakılmaksızın çalışmanın bir yolu var mı? – Ryan

+2

Yanıtı, her iki durumda da geçerli olan bir çözümle güncelleştirdim. –