How to avoid SQL call on FK check

Hello,

I hope my topic is in the right location, otherwise I apologize in advance.
I have an issue with some DB calls that seem unnecessary to me.
Let’s take the following example:

class Car(models.Model):
   name = models.CharField(max_length=255)
   license_plate = models.ForeignKey(LicensePlate, on_delete=models.PROTECT, blank=True, null=True)

   @property
   def is_allowed_on_the_road(self):
      if not self.license_plate:  # << my issue is here
         return False
      # more code
      return True

As far as I observed, is_allowed_on_the_road will make a SQL call to retrieve the license_plate object.
Which as far as I know is not needed to just know if it exist… If the field is filled then there is a license plate attached to the pk stored here, no ?

My question is:
Did I miss a way to avoid this SQL call ?

Thanks in advance
Q

Technically, no.

Depending upon your database, and in some cases how it’s configured, the presence of an ID in the license_plate_id field does not necessarily guarantee that the corresponding row exists in the referenced table.

If you only want to check that there is an ID in that field, you can check by testing license_plate_id. (And, in the majority of cases, that would be sufficient.)

Hello @KenWhitesell ,

Thank you for your answer, it helped a lot
Indeed using _id was what I was looking for since I do not need guarantees in my use-case.

edit: the following "finding" is not worth your time.

From investigating I also discovered that using _id is only “needed” if my Foreign Key is marked as blank=True, null=True. If I only use blank=True, django seems to be able to save the SQL call by default. (I will edit my example to reflect that)

That detail could be interesting for people looking this post in the future. → NO it won’t

Cheers
Q

True, but in that case, you will always need to have a referent for that column. You won’t be able to create a row without it.

Absolutely, I just realized it was non sense.
If the field can not be null then if not self.license_plate makes little sense :slight_smile:
Thank you for the help