模型方法中的django反向查找

时间:2011-01-10 11:33:14

标签: python django django-models

Google有许多在交互式提示中进行反向查找的示例,但没有在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返回last_name?

2 个答案:

答案 0 :(得分: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基本上都是一个设置了unique=True的FK,以及一些比标准FK更整洁的访问者)

答案 1 :(得分:2)

为此,您可以在客户端使用* clientdetails_set *来访问链接到该客户端的所有ClientDetails对象。

该集合是Django的对象集,因此调用方法 all()将检索每个对象。如果您知道只有一个可以做 self.clientdetails_set.all()[0] .last_name

以下是django文档的链接:Link