#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.

Reply via email to