DISQUS

Code Spatter: A Django Model Manager for Soft Deleting Records and How to Customize the Django Admin

  • Metin · 6 months ago
    Great writeup, thanks for that! I'll have question though.
    Say I import SoftDeleteManager from an external file and use it with objects = SoftDeleteManager()
    But now, I loose ability to define additional custom manager methods because objecst is already assigned, right? Is there a way to solve this other than inheriting from multiple manager classes?

    Metin
  • Greg Allard · 6 months ago
    You can do this.
    from somewhere import SoftDeleteManager

    class NewManager(SoftDeleteManager):
    '''new stuff'''

    and in the model
    objects = NewManager()
  • sjstelmach · 5 months ago
    Awesome tutorial... this has been really useful. One thing I've had an issue with is related fields (specifically with to M2M relationships).

    A simplified version of my issue works kind of like this: I have a lot of models that all derive from a base content class (articles, images, galleries, etc.). Articles are able to have related content (via a many to many field), but when I soft delete content, it'll still show up in related content queries on my articles. Is there a good way to get this method working for inherited classes and/or m2m fields?
  • Greg Allard · 5 months ago
    I tested this out with a simple many to many example and I am not getting the soft deleted objects returned. With objects = SoftDeleteManager the many to many queries will be using get_query_set() which won't return the soft deleted records. I might need to see an example of how you are getting the deleted results to be able to figure out what is going on. I tried it with some_object.related_things.all() and the returned set won't have deleted related_things.
  • Dave · 4 months ago
    I think I must be missing something, as I cant see where you're setting the flag "deleted".

    Would overriding the models delete function, setting delete=True and saving suffice?
  • Greg Allard · 4 months ago
    That would work. If you are using a signal (pre_delete or post_delete), you might need to send it from the new function since you wouldn't want to call the real delete.

    I've been doing object.deleted = 1 object.save() and not calling or overriding delete(). That way I still have the option to do the real delete in case I need it. You could probably make a real_delete() function to do that if needed though.