I've got a Django class like this:
class Breakfast(m.Model):
# egg = m.OneToOneField(Egg)
...
class Egg(m.Model):
breakfast = m.OneToOneField(Breakfast, related_name="egg")
Is it possible to have breakfast.egg == None
if there is no Egg
related to the Breakfast
?
Edit: Forgot to mention: I'd rather not change the related_name
to something like related_name="_egg"
, then have something like:
@property
def egg(self):
try:
return self.egg
except ...:
return None
Because I use the name egg
in queries, and I'd rather not have to change the queries to using _egg
.
This custom django field will do exactly what you want:
class SingleRelatedObjectDescriptorReturnsNone(SingleRelatedObjectDescriptor):
def __get__(self, *args, **kwargs):
try:
return super(SingleRelatedObjectDescriptorReturnsNone, self).__get__(*args, **kwargs)
except ObjectDoesNotExist:
return None
class OneToOneOrNoneField(models.OneToOneField):
"""A OneToOneField that returns None if the related object doesn't exist"""
related_accessor_class = SingleRelatedObjectDescriptorReturnsNone
To use it:
class Breakfast(models.Model):
pass
# other fields
class Egg(m.Model):
breakfast = OneToOneOrNoneField(Breakfast, related_name="egg")
breakfast = Breakfast()
assert breakfast.egg == None
I just ran into this problem, and found an odd solution to it: if you select_related(), then the attribute will be None if no related row exists, instead of raising an error.
>>> print Breakfast.objects.get(pk=1).egg
Traceback (most recent call last):
...
DoesNotExist: Egg matching query does not exist
>>> print Breakfast.objects.select_related("egg").get(pk=1).egg
None
I have no idea if this can be considered a stable feature though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With