Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - delete an object without deleting its related objects

I have two models:

class Client(models.Model):
    some_field = models.CharField()

class Ticket(models.Model):
    client = models.ForeignKey(Client)

Tickets are FOREVER in my system, but I want users to be able to delete clients they don't want anymore. Currently it'll delete all the tickets created by the Client.

  1. Is this a bad idea (architecturally speaking), and should I just mark them as not_needed or something instead?
  2. If it's not a bad idea, what's the best way to do it, while remaining DRY. I don't want to have to override delete() for each model that does this, but will if I have to (what's the best way to do that, if that's the only way).
like image 911
orokusaki Avatar asked Sep 10 '10 22:09

orokusaki


2 Answers

So this question is very old but in case someone runs across it (like I did): starting from Django 1.3, you can use the on_delete parameter for ForeignKey models, as described here.

like image 123
Jonas Avatar answered Nov 13 '22 13:11

Jonas


The django.contrib.auth module has to deal with this same problem in the User model. Their solution is to have:

class User(models.Model):
    # ...
    is_active = models.BooleanField(default=True)
    # ...

So "deleting" a User is just setting is_active to False. Everything that works with Users needs to check is_active.

For the record, I think deleting Clients in this case is a Bad Idea.

But for the sake of argument, if you delete a Client, then its related Tickets need to first become clientless. Change the model for Ticket to:

class Ticket(models.Model):
    client = models.ForeignKey(Client, null=True, blank=True, 
        related_name='tickets')

Then, to delete a Client, do:

for ticket in clientToDelete.tickets:
    ticket.client = None
    ticket.save()
clientToDelete.delete()

You can put this code into Client's delete method, but it will get skipped if you do a mass (i.e. QuerySet-based) delete of Clients.

like image 22
Mike DeSimone Avatar answered Nov 13 '22 12:11

Mike DeSimone