Opened 4 years ago

Closed 3 months ago

Last modified 3 months ago

#15579 closed New feature (fixed)

Please add support to delete specialization , while preserving base class instance (multi-table inheritance)

Reported by: zimnyx Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: MarkusH, sokandpal@… Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Example:
I got multi-table inheritance: Base(Model) and Specific(Base). I got instance of Specific. Sometimes there is a need to delete only Specific leaving Base part in database. Currently if I call delete() on specialization, recursive delete takes place, so Base instance is being deleted too.

Change History (16)

comment:1 Changed 4 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to wontfix
  • Status changed from new to closed

This can be done right now by setting the parent link to None on the child object prior to deletion. This is at least as intuitive as any specific API for this feature that I can think of.

comment:2 Changed 4 years ago by zimnyx

  • Resolution wontfix deleted
  • Status changed from closed to reopened

It doesn't seem to work.

Please take a look on this sample code:

class List(models.Model):      
    name = models.CharField(max_length=10) 
  
class SpecificList(List):      
    specific_name = models.CharField(max_length=10) 

Let's create specialization instance

>>> s = SpecificList(name='bear', specific_name='sasquatch')
>>> s.save()
110315 11:48:35	   21 Query	INSERT INTO `list_list` (`name`) VALUES ('bear')
		   21 Query	commit
		   21 Query	SELECT ** FROM `list_specificlist` WHERE `list_specificlist`.`list_ptr_id` = 3  LIMIT 1
		   21 Query	INSERT INTO `list_specificlist` (`list_ptr_id`, `specific_name`) VALUES (3, 'sasquatch')
		   21 Query	commit

And now delete (upcast) it as you suggested:

>>> s.list_ptr = None
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/srv/django-bugi/nowa/mypro/django/db/models/fields/related.py", line 327, in __set__
    (instance._meta.object_name, self.field.name))
ValueError: Cannot assign None: "SpecificList.list_ptr" does not allow null values.

I also tried setting *_ptr_id to None and then delete:

>>> s.list_ptr_id = None
>>> s.delete()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/srv/django-bugi/nowa/mypro/django/db/models/base.py", line 577, in delete
    assert self._get_pk_val() is not None, "%s object can't be deleted because its %s attribute is set to None." % (self._meta.object_name, self._meta.pk.attname)
AssertionError: SpecificList object can't be deleted because its list_ptr_id attribute is set to None.

This does not work either.

Do I misunderstood you or this feature just doesn't work?

comment:3 Changed 4 years ago by lukeplant

  • Type set to New feature

comment:4 Changed 4 years ago by lukeplant

  • Severity set to Normal

comment:5 Changed 4 years ago by julien

  • Resolution set to wontfix
  • Status changed from reopened to closed

Please do not reopen a ticket closed by a core dev. If you would like to tackle this issue please bring it up to the django-developers mailing list.

comment:6 Changed 4 years ago by russellm

  • Resolution wontfix deleted
  • Status changed from closed to reopened
  • Triage Stage changed from Unreviewed to Accepted

My apologies -- it appears that your original report was correct. I closed it because I thought I had code in production that was using the trick I suggested; however, when I checked, it turns out I'm reparenting a child, not deleting it.

comment:7 Changed 3 years ago by aaugustin

  • UI/UX unset

Change UI/UX from NULL to False.

comment:8 Changed 3 years ago by aaugustin

  • Easy pickings unset

Change Easy pickings from NULL to False.

comment:9 Changed 2 years ago by aaugustin

  • Status changed from reopened to new

comment:10 Changed 4 months ago by MarkusH

  • Cc MarkusH added

comment:11 Changed 4 months ago by coldmind

  • Cc sokandpal@… added
  • Has patch set

comment:12 Changed 4 months ago by MarkusH

  • Needs documentation set

comment:13 Changed 4 months ago by coldmind

  • Needs documentation unset

comment:14 Changed 3 months ago by timgraham

  • Triage Stage changed from Accepted to Ready for checkin

comment:15 Changed 3 months ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from new to closed

In 81c2d9f6:

Fixed #15579 -- Added ability to delete only child models in multi-table inheritance.

comment:16 Changed 3 months ago by Tim Graham <timograham@…>

In 71c638fc:

Fixed typo in refs #15579 comment.

Note: See TracTickets for help on using tickets.
Back to Top