2011-01-10 75 views
1

谷歌有很多在交互提示中做反向查找的例子,但是沒有一個在django模型中作爲一個方法來做它們。django反向查找模型方法

我有以下models.py文件:

class Client(models.Model): 
    ... 

    def __unicode__(self): 
     return ??? 

class ClientDetails(models.Model): 
    client = models.ForeignKey(Client, null=True) 
    created = models.DateTimeField(default=datetime.now) 
    created_by = models.ForeignKey(User, null=True) 
    name_title = models.CharField(max_length=3, choices=NAME_TITLE_CHOICES) 
    first_name = models.CharField(max_length=40) 
    middle_name = models.CharField(max_length=40) 
    last_name = models.CharField(max_length=40) 
    ... 

如何獲得客戶端的方法來從ClientDetails返回姓氏?

+1

有每一個客戶的多個細節(這是一種方式FK工作)。您希望clientdetails_set中哪個ClientDetails? – 2011-01-10 11:38:25

+0

我想引用last_name – Sevenearths 2011-01-10 12:04:28

+0

是的。你想要last_name。哪個姓氏? `clientdetails_set`將有多於一行。當有2個(或更多)行時,哪一行具有正確的last_name值? – 2011-01-10 13:13:48

回答

3

如果一個ClientDetails對象只應該與一個Client對象關聯,那麼我會將您的FK更改爲OneToOneField,它將爲您提供一個整齊的反向訪問器,它只能連接給定客戶端和其關聯ClientDetails。然後,你可以這樣做:

try: 
    return self.clientdetails.last_name 
except ClientDetails.DoesNotExist: 
    ##handle it here, returning a graceful message 

另外,如果你保持它作爲FK,那麼你就必須做一些事情,如:

try: 
    self.clientdetails_set.all()[0].last_name 
except IndexError, e: 
    ## handle exception here 

但這裏使用FK是脆的,而不是偉大的形式(因爲異常處理意味着:如果沒有返回,那麼您將得到一個IndexError。此外,可能有多個ClientDetails對象鏈接到該客戶端,並且您只會在此處獲得第一個的詳細信息)

所以,我真的會建議使用OneToOneField而不是FK。 (所有OneToOneField基本上都是一個FK,其上設置了unique=True以及一些比標準FK更接近的訪問器)

2

爲此您可以在客戶端使用* clientdetails_set *來訪問鏈接到該客戶端的所有ClientDetails對象。

該設置是一個從Django設置的對象,因此調用方法all()將檢索每個對象。如果你只知道有一個你可以做self.clientdetails_set.all()[0] .last_name

這裏的鏈接,Django文檔:Link