success method get_context_data generic from form createview based django view cascade

method - get_context_data django



¿Cómo mostrar elementos relacionados usando DeleteView en Django? (3)

Estoy haciendo una vista para eliminar (usando la vista genérica DeleteView de Django) una instancia de un modelo, pero en cascada y elimina las instancias de otros modelos:

url(r''^person/(?P<pk>/d+)/delete/$'', login_required(DeleteView.as_view(model=Person, success_url=''/person/'', template_name=''delete.html'')), name=''person_delete''),

Lo que quiero hacer es mostrar la lista de elementos relacionados que se van a eliminar, como lo hace la interfaz de administración, como:

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


Actualización: desde Django 1.9+ NestedObject se debe importar desde django.contrib.admin.util s

from django.contrib.admin.utils import NestedObjects


Puede usar la clase Collector usa Django para determinar qué objetos eliminar en la cascada. Instálelo y luego invoque la collect en él pasando los objetos que desea eliminar. Espera una lista o un conjunto de consultas, por lo que si solo tiene un objeto, simplemente colóquelo dentro de una lista:

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 devuelve un generador, por lo que solo puede usarlo dentro del contexto de un bucle. Si prefiere una estructura de datos real que pueda manipular, el paquete admin contrib tiene una subclase de Collector llamada NestedObjects , que funciona de la misma manera, pero tiene un método nested que devuelve una lista jerárquica:

from django.contrib.admin.utils import NestedObjects collector = NestedObjects(using=''default'') # or specific database collector.collect([some_instance]) to_delete = collector.nested()

Actualizado: desde Django 1.9, django.contrib.admin.util cambió su nombre a django.contrib.admin.utils


Utilizo una modifcación reducida de get_deleted_objects () del administrador y la uso para extender mi contexto en get_context en la vista de eliminación:

definir en algún lugar

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

entonces en tus puntos de vista

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

Ahora puedes usarlos en tu plantilla.

<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>

La mayoría es solo copiar / pegar / editar / eliminar no deseado de django admin