[Django]-How to find all Django foreign key references to an instance

4👍

You can use Django’s reverse foreign key support.

Say you have two models, like so:

class Foo(models.Model):
   name = models.CharField(max_length=10)

class Bar(models.Model):
   descr = models.CharField(max_length=100)
   foo = models.ForeignKey(Foo)

Then you know you can do bar_instance.foo to access the Foo object it keys to. But you can use the reverse foreign key on a Foo instance to get all the Bar objects that point to it using, e.g, foo.bar_set.

👤Joseph

2👍

Personally, I think the best option is to avoid the cascaded deletion.

Declaring the foreign keys in the related models with the proper Django option, e.g.

on_delete=models.SET_NULL

should suffice.

Borrowing the sample models from @Joseph’s answer:

class Foo(models.Model):
   name = models.CharField(max_length=10)

class Bar(models.Model):
   descr = models.CharField(max_length=100)
   foo = models.ForeignKey(Foo, blank=True, null=True, on_delete=models.SET_NULL))

As described in the official Django docs, here are the predefined behaviours you can use and experiment with:

  • SET_NULL: Set the ForeignKey null; this is only possible if null is
    True.

  • SET_DEFAULT: Set the ForeignKey to its default value; a default for
    the ForeignKey must be set.

  • SET(): Set the ForeignKey to the value passed to SET(), or if a
    callable is passed in, the result of calling it. In most cases, passing a callable will be necessary to avoid executing queries at the time your models.py is imported:

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models

def get_sentinel_user():
    return get_user_model().objects.get_or_create(username='deleted')[0]

class MyModel(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.SET(get_sentinel_user))
  • DO_NOTHING: Take no action. If your database backend enforces
    referential integrity, this will cause an IntegrityError unless you
    manually add an SQL ON DELETE constraint to the database field

Leave a comment