I have a Django app with two models:
class Foo(models.Model):
baz = models.CharField(max_length=100)
class Bar(models.Model):
foo = models.ForeignKey(Foo)
In a view, I want to delete a Bar
object. Currently it's done with:
foo_to_delete = Foo.objects.get(pk=1)
if not foo_to_delete.bar_set.exists(): # step 1
foo_to_delete.delete() # step 2
But now if at the time between the step 1 and the step 2, someone saves a new Bar
object with the foo
field pointing to foo_to_delete
object, this new Bar
object would be deleted by step 2.
Is there any way to avoid this, maybe by doing a single SQL call ? Does the Django ORM provides something for doing this kind of check before deletion safely ?
I think I have solved the problem using models.PROTECT
.
The models now looks like this:
class Foo(models.Model):
baz = models.CharField(max_length=100)
class Bar(models.Model):
foo = models.ForeignKey(Foo, on_delete=models.PROTECT)
And the view is like this:
foo_to_delete = Foo.objects.get(pk=1)
try:
foo_to_delete.delete()
except models.ProtectedError:
# show an error message
This seems to be mapped to only one SQL query, thus making it safe (I think).