Django check if a related object exists error: RelatedObjectDoesNotExist

PythonDjango

Python Problem Overview


I have a method has_related_object in my model that needs to check if a related object exists

class Business(base):
      name =  models.CharField(max_length=100, blank=True, null=True)

  def has_related_object(self):
        return (self.customers is not None) and (self.car is not None)


class Customer(base):
      name =  models.CharField(max_length=100, blank=True, null=True)
      person = models.OneToOneField('Business', related_name="customer")

But I get the error:

> Business.has_related_object() > > RelatedObjectDoesNotExist: Business has no customer.

Python Solutions


Solution 1 - Python

Use hasattr(self, 'customers') to avoid the exception check as recommended in Django docs:

def has_related_object(self):
    return hasattr(self, 'customers') and self.car is not None

Solution 2 - Python

This is because the ORM has to go to the database to check to see if customer exists. Since it doesn't exist, it raises an exception.

You'll have to change your method to the following:

def has_related_object(self):
    has_customer = False
    try:
        has_customer = (self.customers is not None)
    except Customer.DoesNotExist:
        pass
    return has_customer and (self.car is not None)

I don't know the situation with self.car so I'll leave it to you to adjust it if it needs it.

Side note: If you were doing this on a Model that has the ForeignKeyField or OneToOneField on it, you would be able to do the following as a shortcut to avoid the database query.

def has_business(self):
    return self.business_id is not None

Solution 3 - Python

You probably had created the user before while debuging and has no profile, so even after now coding the automation in, they still have no profile try the code below in your signal.py file, then create a superuser, log in as the super user and then add the first account's profile from there. That worked for me...

@receiver(post_save, sender=User, dispatch_uid='save_new_user_profile')
def save_profile(sender, instance, created, **kwargs):
    user = instance
    if created:
        profile = UserProfile(user=user)
        profile.save()

Solution 4 - Python

Although it's an old question, I thought this can be helpful for someone looking to handle this type of exception, especially when you want to check for OneToOne relations.

My solution is to use ObjectDoesNotExist from django.core.exceptions:

from django.core.exceptions import ObjectDoesNotExist

class Business(base):
      name =  models.CharField(max_length=100, blank=True, null=True)

	def has_related_object(self):
		try:
			self.customers
			self.car
			return True
		except ObjectDoesNotExist:
			return False


class Customer(base):
      name =  models.CharField(max_length=100, blank=True, null=True)
      person = models.OneToOneField('Business', related_name="customer")

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPrometheusView Question on Stackoverflow
Solution 1 - PythonmrtsView Answer on Stackoverflow
Solution 2 - PythonschillingtView Answer on Stackoverflow
Solution 3 - PythonRonny KView Answer on Stackoverflow
Solution 4 - PythonMehdi ZareView Answer on Stackoverflow