2011-12-30 50 views
1

我正在爲一個非營利的,在django中製作一個非常輕量級的crm。關注此問題的車型有:基於MTM字段過濾Django查詢集


class Human(models.Model): 
    first_name = models.CharField(max_length=200) 
    last_name = models.CharField(max_length=200) 
    nickname = models.CharField(max_length=200, blank=True, null=True) 
    middle_name = models.CharField(max_length=200, blank=True, null=True) 

    def __unicode__(self): 
     namestring = self.last_name+','+self.first_name 
     if self.nickname: 
      namestring += '('+self.nickname+')' 
     elif self.middle_name: 
      namestring += '('+self.middle_name+')' 
     return namestring 

class PhoneNumber(models.Model): 
    humans = models.ManyToManyField(Human, through='HumanToPhoneNumber') 
    nation_code = models.IntegerField(blank=True, null=True) 
    area_code = models.IntegerField() 
    local_number = models.IntegerField() 

    def __unicode__(self): 
     what_to_call_it = "("+str(self.area_code)+")"+str(self.local_number) 
     if (self.nation_code): 
      what_to_call_it = str(self.nation_code)+what_to_call_it 
     return what_to_call_it 


class HumanToPhoneNumber(models.Model): 
    human = models.ForeignKey(Human) 
    phone_number = models.ForeignKey(PhoneNumber) 
    begin_date = models.DateTimeField('begin date') 
    end_date = models.DateTimeField('end date', null=True, blank=True) 
    active = models.BooleanField(default=True) 
    preferred = models.BooleanField(default=False) 
    label = models.CharField(max_length=200, blank=True, null=True) 

    def __unicode__(self): 
     what_to_call_it = str(self.human) 
     if self.label: 
      what_to_call_it += "("+self.label+")" 
     return what_to_call_it 

當我顯示了一個人的電話號碼,我只想表明,仍然是「積極」的那些,也可以通過的首選方法顯示標記聯繫人(有類似的電子郵件地址,humantoemail,地址,humantoaddress)。不止一個人可以有相同的號碼,而且一個人可以有多個號碼,所以它是多對多的。

對此的看法是:


def human(request, human_id): 
    p = get_object_or_404(Human, pk=human_id) 
    emails = p.emailaddress_set.all() 
    emails.filter(emailaddress__humantoemailaddress.active=True) #this line does not work 
    phone_numbers = p.phonenumber_set.all() 
    addresses = p.physicaladdress_set.all()  
    return render_to_response('person.html', {'person': p, 'emails': emails, 'phone_numbers': phone_numbers, 'addresses': addresses}) 

我試着在上面有一些變化,但我顯然不是groking如何,我的意思,以接觸到許多「激活」場一對多的關係。我無法將該字段放在電子郵件,電話號碼或PhysicalAddress模型上,因爲它可能仍然對一個人有效,但不再對另一個人有效,對於「首選」也類似。

在django視圖中寫這個查詢的正確方法是什麼?任何幫助表示讚賞。哦,我正在使用Django 1.3,以防萬一。

編輯:修正在上面一個錯字,以及試圖在電話號碼不同的過濾器從Django文檔複製或多或少正好在MTM:

def human(request, human_id): 
p = get_object_or_404(Human, pk=human_id) 
emails = p.emailaddress_set.filter(humantoemailaddress__active=True) <--- does not work 
phone_numbers = p.phone_number_set.filter(humantophonenumber__begin_date__gt=date(2011,1,1)) <--- does not work either 
addresses = p.physicaladdress_set.all()  
return render_to_response('person.html', {'person': p, 'emails': emails, 'phone_numbers': phone_numbers, 'addresses': addresses}) 

任何幫助表示讚賞,並讓我知道,如果有我應該添加任何其他細節。

第二編輯:D'oh!它有助於編輯正確的文件。我已經檢查了下面的答案,這實際上工作得很好。

+1

有一個錯字,emailaddress__humantoemailaddress.active應該是emailaddress__humantoemailaddress__active。 – jpic 2011-12-30 17:22:24

回答

1

您可以使用雙下劃線表示法對連接表中的字段進行過濾,例如, humantophonenumber__active

例如:

p = get_object_or_404(Human, pk=human_id) 
phone_numbers = p.phone_number_set.filter(humantophonenumber__active=True) 

爲了進一步甲殼蟲爲基礎的實施例中,檢查了Django docs