19👍
Harold’s answer pointed me in the right direction. This is a sketch on the way I implemented it (on a french legacy database, hence the slightly odd naming convention):
class Factures(models.Model):
idFacture = models.IntegerField(primary_key=True)
idLettrage = models.ForeignKey('Lettrage', db_column='idLettrage', null=True, blank=True)
class Paiements(models.Model):
idPaiement = models.IntegerField(primary_key=True)
idLettrage = models.ForeignKey('Lettrage', db_column='idLettrage', null=True, blank=True)
class Lettrage(models.Model):
idLettrage = models.IntegerField(primary_key=True)
def delete(self):
"""Dettaches factures and paiements from current lettre before deleting"""
self.factures_set.clear()
self.paiements_set.clear()
super(Lettrage, self).delete()
25👍
Django 1.3a1 and up support this via ForeignKey
‘s on_delete
argument.
The following example sets the field NULL
upon deletion of the foreign key. See the documentation for more options.
user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)
- [Django]-Django runserver permanent
- [Django]-How do I use a dictionary to update fields in Django models?
- [Django]-SyntaxError: Generator expression must be parenthesized
7👍
Django’s ForeignKey manager has a method called clear() that removes all objects from the related object set. Calling that first, then deleting your object should work. The dependent objects will have their foreign keys set to None (if allowed in your model).
A short description here:
http://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward
- [Django]-Django templates – split string to array
- [Django]-Django, after upgrade: MySQL server has gone away
- [Django]-How do I render jinja2 output to a file in Python instead of a Browser
3👍
FYI – a feature request for this exists in the django source repository at http://code.djangoproject.com/ticket/7539. It looks like this topic is getting some attention. Hopefully it will be included in future Django releases.
The ticket includes patches to Django’s core to implement an “on_delete” optional parameter to models.ForeignKey(…) that lets you specify what happens when the pointed to Model is deleted, including turning off the default ON DELETE CASCADE behavior.
- [Django]-Django: import auth user to the model
- [Django]-Which Postgres value should I use in Django's DATABASE_ENGINE?
- [Django]-The number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS
2👍
Well, looking at delete method
def delete(self):
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)
# Find all the objects than need to be deleted.
seen_objs = CollectedObjects()
self._collect_sub_objects(seen_objs)
# Actually delete the objects.
delete_objects(seen_objs)
I’d say overriding delete should be enough…untested code would be
def delete(self):
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)
# Find all the objects than need to be deleted.
seen_objs = CollectedObjects()
seen_objs.add(model=self.__class__, pk=self.pk, obj=self, parent_model=None)
# Actually delete the objects.
delete_objects(seen_objs)
- [Django]-Django database query: How to get object by id?
- [Django]-Disallowed Host at Django
- [Django]-Django multiple and dynamic databases
1👍
One way is to call clear method before deleting, documentation here which basically “clears” the relationship.
One problem thought: it’s not auto by itself. You can choose: call it every time you don’t want cascade, or use the pre_delete signal to send clear before each delete, of course it’ll give you problems when you DO want delete – cascade.
Or you can contribute to the django community and add the keyword argument to delete, maybe it’ll be in django 1.3?:D
- [Django]-How to migrate back from initial migration in Django 1.7?
- [Django]-Django migration with uuid field generates duplicated values
- [Django]-Django custom management commands: AttributeError: 'module' object has no attribute 'Command'
0👍
Re: http://code.djangoproject.com/ticket/7539
No attention as of Django 1.2.1, June 2010. I guess we need to “watch that space”.
- [Django]-Django migrations RunPython not able to call model methods
- [Django]-Django: Obtaining the absolute URL without access to a request object
- [Django]-How can I disable Django's admin in a deployed project, but keep it for local development?