2011-01-10 97 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