#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 django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/069.05a379f732f1c558e3b4fab9cfc7a3f8%40djangoproject.com.

Reply via email to