I am doing a view to delete (using the generic view DeleteView from Django) an instance from a model, but it cascades and deletes instances from other models:
url(r'^person/(?P<pk>\d+)/delete/$', login_required(DeleteView.as_view(model=Person, success_url='/person/', template_name='delete.html')), name='person_delete'),
What I want to do is to show the list of related items that are going to be deleted, as the admin interface does, like:
Are you sure you are going to delete Person NAMEOFTHEPERSON?
By deleting it, you are also going to delete:
CLASSNAME1: CLASSOBJECT1 ; CLASSNAME2: CLASSOBJECT2 ; CLASSNAME3: CLASSOBJECT3 ; etc
DeleteView – Class Based Views Django Last Updated : 24 Jun, 2021 Delete View refers to a view (logic) to delete a particular instance of a table from the database. It is used to delete entries in the database for example, deleting an article at geeksforgeeks.
We have already discussed basics of Delete View in Delete View – Function based Views Django. Class-based views provide an alternative way to implement views as Python objects instead of functions. They do not replace function-based views, but have certain differences and advantages when compared to function-based views:
Since we are getting a specific object of a database table to delete, we use the built-in get_object_or_404 function in Django. This allows us to get a specific object from the database table that we can delete. Since we are working with the Movie database table, we import Movie from models.py
The DeleteView won't delete on GET requests; this is your opportunity to provide a confirmation template (you can provide the name in the template_name class attribute) with a "Yes I'm sure" button which POST s to this view.
You can use the Collector
class Django uses to determine what objects to delete in the cascade. Instantiate it and then call collect
on it passing the objects you intend to delete. It expects a list or queryset, so if you only have one object, just put in inside a list:
from django.db.models.deletion import Collector collector = Collector(using='default') # or specific database collector.collect([some_instance]) for model, instance in collector.instances_with_model(): # do something
instances_with_model
returns a generator, so you can only use it within the context of a loop. If you'd prefer an actual data structure that you can manipulate, the admin
contrib package has a Collector
subclass called NestedObjects
, that works the same way, but has a nested
method that returns a hierarchical list:
from django.contrib.admin.utils import NestedObjects collector = NestedObjects(using='default') # or specific database collector.collect([some_instance]) to_delete = collector.nested()
Updated: Since Django 1.9, django.contrib.admin.util was renamed to django.contrib.admin.utils
I use a cutdown modifcation of get_deleted_objects() from the admin and use it to extend my context in get_context in the delete view:
from django.contrib.admin.utils import NestedObjects from django.utils.text import capfirst from django.utils.encoding import force_text def get_deleted_objects(objs): collector = NestedObjects(using='default') collector.collect(objs) # def format_callback(obj): opts = obj._meta no_edit_link = '%s: %s' % (capfirst(opts.verbose_name), force_text(obj)) return no_edit_link # to_delete = collector.nested(format_callback) protected = [format_callback(obj) for obj in collector.protected] model_count = {model._meta.verbose_name_plural: len(objs) for model, objs in collector.model_objs.items()} # return to_delete, model_count, protected
from somewhere import get_deleted_objects # class ExampleDelete(DeleteView): # ... def get_context_data(self, **kwargs): # context = super().get_context_data(**kwargs) # deletable_objects, model_count, protected = get_deleted_objects([self.object]) # context['deletable_objects']=deletable_objects context['model_count']=dict(model_count).items() context['protected']=protected # return context
<table> <tr> <th>Name</th> <th>Amount</th> </tr> {% for model_name, object_count in model_count %} <tr> <td>{{ model_name|capfirst }}</td> <td>{{ object_count }}</td> </tr> {% endfor %} </table> <p> <ul> {{ deletable_objects|unordered_list }} </ul> </p>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With