#31600: Calling .delete() on a queryset doesn't delete related objects
-------------------------------+--------------------------------------
Reporter: אורי | Owner: nobody
Type: Bug | Status: new
Component: Uncategorized | Version: 3.0
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by אורי:
Old description:
> I created a new test and it had users and I deleted them:
>
> `User.objects.all().exclude(pk=self.user_1.pk).delete()`
>
> The User model has related models with `on_delete=models.CASCADE` which
> should be deleted as well.
>
> But in my test, I got this exception:
>
> {{{
> ======================================================================
> ERROR: test_like_list_views_titles_with_empty_lists
> (speedy.match.likes.tests.test_views.LikeListViewsEnglishTestCase)
> ----------------------------------------------------------------------
> Traceback (most recent call last):
> File "env\lib\site-packages\django\db\backends\utils.py", line 84, in
> _execute
> return self.cursor.execute(sql)
> psycopg2.errors.ForeignKeyViolation: insert or update on table
> "net_accounts_siteprofile" violates foreign key constraint
> "net_accounts_sitepro_user_id_c96775a1_fk_accounts_"
> DETAIL: Key (user_id)=(403828609159078) is not present in table
> "accounts_user".
>
> The above exception was the direct cause of the following exception:
>
> Traceback (most recent call last):
> File "env\lib\site-packages\django\test\testcases.py", line 274, in
> __call__
> self._post_teardown()
> File "env\lib\site-packages\django\test\testcases.py", line 1009, in
> _post_teardown
> self._fixture_teardown()
> File "env\lib\site-packages\django\test\testcases.py", line 1177, in
> _fixture_teardown
> connections[db_name].check_constraints()
> File "env\lib\site-packages\django\db\backends\postgresql\base.py",
> line 276, in check_constraints
> self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE')
> File "env\lib\site-packages\django\db\backends\utils.py", line 68, in
> execute
> return self._execute_with_wrappers(sql, params, many=False,
> executor=self._execute)
> File "env\lib\site-packages\django\db\backends\utils.py", line 77, in
> _execute_with_wrappers
> return executor(sql, params, many, context)
> File "env\lib\site-packages\django\db\backends\utils.py", line 86, in
> _execute
> return self.cursor.execute(sql, params)
> File "env\lib\site-packages\django\db\utils.py", line 90, in __exit__
> raise dj_exc_value.with_traceback(traceback) from exc_value
> File "env\lib\site-packages\django\db\backends\utils.py", line 84, in
> _execute
> return self.cursor.execute(sql)
> django.db.utils.IntegrityError: insert or update on table
> "net_accounts_siteprofile" violates foreign key constraint
> "net_accounts_sitepro_user_id_c96775a1_fk_accounts_"
> DETAIL: Key (user_id)=(403828609159078) is not present in table
> "accounts_user".
>
> ----------------------------------------------------------------------
> Ran 1 test in 7.425s
> }}}
>
> I think this exception is because the users I deleted.
> `net_accounts_siteprofile` refers to the `SiteProfile` model which should
> be deleted when deleting a user by on_delete=models.CASCADE .
>
> I checked and eventually I found out that changing:
>
> `User.objects.all().exclude(pk=self.user_1.pk).delete()`
>
> To:
>
> {{{
> for user in User.objects.all().exclude(pk=self.user_1.pk):
> user.delete()
> }}}
>
> Fixes the problem. But I expected related objects to be deleted by the
> first query too. Does it mean I can't safely delete users in bulk by
> `.delete()`? And if it does, how do I disable it so trying to delete
> users in bulk will raise an exception?
>
> I would like either to fix the queryset bulk `.delete()` method to delete
> related objects too, or to completely disable bulk deletions in Django.
> Is there a simple way to define a manager which doesn't have this bulk
> delete feature?
New description:
I created a new test and it had users and I deleted them:
`User.objects.all().exclude(pk=self.user_1.pk).delete()`
The `User` model has related models with `on_delete=models.CASCADE` which
should be deleted as well.
But in my test, I got this exception:
{{{
======================================================================
ERROR: test_like_list_views_titles_with_empty_lists
(speedy.match.likes.tests.test_views.LikeListViewsEnglishTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "env\lib\site-packages\django\db\backends\utils.py", line 84, in
_execute
return self.cursor.execute(sql)
psycopg2.errors.ForeignKeyViolation: insert or update on table
"net_accounts_siteprofile" violates foreign key constraint
"net_accounts_sitepro_user_id_c96775a1_fk_accounts_"
DETAIL: Key (user_id)=(403828609159078) is not present in table
"accounts_user".
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "env\lib\site-packages\django\test\testcases.py", line 274, in
__call__
self._post_teardown()
File "env\lib\site-packages\django\test\testcases.py", line 1009, in
_post_teardown
self._fixture_teardown()
File "env\lib\site-packages\django\test\testcases.py", line 1177, in
_fixture_teardown
connections[db_name].check_constraints()
File "env\lib\site-packages\django\db\backends\postgresql\base.py", line
276, in check_constraints
self.cursor().execute('SET CONSTRAINTS ALL IMMEDIATE')
File "env\lib\site-packages\django\db\backends\utils.py", line 68, in
execute
return self._execute_with_wrappers(sql, params, many=False,
executor=self._execute)
File "env\lib\site-packages\django\db\backends\utils.py", line 77, in
_execute_with_wrappers
return executor(sql, params, many, context)
File "env\lib\site-packages\django\db\backends\utils.py", line 86, in
_execute
return self.cursor.execute(sql, params)
File "env\lib\site-packages\django\db\utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "env\lib\site-packages\django\db\backends\utils.py", line 84, in
_execute
return self.cursor.execute(sql)
django.db.utils.IntegrityError: insert or update on table
"net_accounts_siteprofile" violates foreign key constraint
"net_accounts_sitepro_user_id_c96775a1_fk_accounts_"
DETAIL: Key (user_id)=(403828609159078) is not present in table
"accounts_user".
----------------------------------------------------------------------
Ran 1 test in 7.425s
}}}
I think this exception is because the users I deleted.
`net_accounts_siteprofile` refers to the `SiteProfile` model which should
be deleted when deleting a user by on_delete=models.CASCADE .
I checked and eventually I found out that changing:
`User.objects.all().exclude(pk=self.user_1.pk).delete()`
To:
{{{
for user in User.objects.all().exclude(pk=self.user_1.pk):
user.delete()
}}}
Fixes the problem. But I expected related objects to be deleted by the
first query too. Does it mean I can't safely delete users in bulk by
`.delete()`? And if it does, how do I disable it so trying to delete users
in bulk will raise an exception?
I would like either to fix the queryset bulk `.delete()` method to delete
related objects too, or to completely disable bulk deletions in Django. Is
there a simple way to define a manager which doesn't have this bulk delete
feature?
--
--
Ticket URL: <https://code.djangoproject.com/ticket/31600#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/069.05a379f732f1c558e3b4fab9cfc7a3f8%40djangoproject.com.