0

I have a one to one relationship defined on a model. Let's call the parent model A and the related model B. B will not always exist. When I'm interacting with an instance of A how can I determine if B exists without having to catch DoesNotExist? When I attempt to access an instance of B (e.g. print a.b) I receive a DoesNotExist exception. When there is a DB row corresponding to the relation it works. This is on django 1.5.

Simplified model definition off the top of my head (not tested in this form):

class A:
    ...

class B:
    a = models.OneToOneField(A, related_name='a')
    name = models.TextField(...)

fields = ['b__name']
a = A.object.filter(pk=id).selected_related(*fields)
print(a.b)

Table B has a foreign key of a_id.

My reason for the question was to determine if there was a cleaner way to do this via an API rather than catching an exception.

Brad
  • 109
  • 10

2 Answers2

1

If I understand this correctly, firstly the attribute "related_name" is used to refer the current object from the reversed foreign key object, so the model definition should be something like :

class A:
   ...

class B:
    a = models.OneToOneField(A, related_name='alias_for_b')
    name = models.TextField(...)

and the validation code could be simply:

if hasattr(a, 'alias_for_b'):
    print(a.b) or print(a.alias_for_b)

Hope this helps !!

0

Let's say you have your instance of A a. As you correctly say you can access the related instance of B b with something like print(a.b) (Python 3 syntax). If it's possible that there will be no related item and you don't want the user to get an error then you need to wrap that call to b up in something. Something like:

try:
    print(a.b)
except:
    print('Nothing to see here')

That checks for b's presence before trying to present it, and won't do so if it's not there.

Alternatively, you could approach this from the other direction. Given an instance a you could look up B.objects.filter(your_relation_name=a). That way won't involve any error catching, just a blank queryset if no such b exists.

cms_mgr
  • 1,977
  • 2
  • 17
  • 31
  • Why catching Exception would be better than catching DoesNotExist? – Emanuele Paolini Oct 03 '14 at 16:06
  • I wouldn't be concerned about efficiency, it's more error prone as it catches all exceptions, even unexpected ones. – Brad Oct 03 '14 at 17:49
  • My intent was to not have to catch an exception. I'm looking for an API. Seems strange this isn't possible without catching an exception. – Brad Oct 03 '14 at 17:50
  • Understood, I've added a different way to do this that's closer to what you describe. Haven't tested it as I'm away from my dev machine but it should work. – cms_mgr Oct 03 '14 at 21:01