开发者

django reverse lookup in model method

Google has lots of examples of doing reverse lookup in the interactive prompt but none of doing them inside a django model as a method.

I have the following models.py file:

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_lengt开发者_如何学编程h=40)
    ...

How do I get the client method to return last_name from ClientDetails?


If a ClientDetails object should only ever be associated with a single Client object, then I would change your FK to a OneToOneField, which will provide you with a neat reverse accessor that can only ever link between a given Client and its associated ClientDetails. Then you can do:

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

Alternatively, if you kept it as a FK, then you'd have to do something like:

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

but using a FK here is brittle and not great form (as the exception-handling implies: if there is none returned, then you'll get an IndexError. Also, there might be more than one ClientDetails object linked to that Client, and you'd only get the details of the first one here.)

So, I really would recommend using a OneToOneField instead of that FK. (All a OneToOneField is basically an FK with unique=True set on it and some neater accessors than standard FKs)


For that you can use in client the *clientdetails_set* to access all the ClientDetails objects that are linked to that client.

The set is an object set from Django, so calling the method all() will retrieve every of the objects. If you know there's only one you can do self.clientdetails_set.all()[0].last_name

Here's the link for the django documentation: Link

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜