简体   繁体   中英

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_length=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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM