improved deletion of recipes

This commit is contained in:
vabene1111 2021-11-04 12:27:21 +01:00
parent 980dc48eb8
commit 1fad1d2b8f
3 changed files with 62 additions and 28 deletions

View File

@ -458,6 +458,9 @@ class Step(ExportModelOperationsMixin('step'), models.Model, PermissionModelMixi
from cookbook.helper.template_helper import render_instructions
return render_instructions(self)
def __str__(self):
return f'{self.pk} {self.name}'
class Meta:
ordering = ['order', 'pk']
indexes = (GinIndex(fields=["search_vector"]),)

View File

@ -22,13 +22,11 @@
</div>
{{ form|crispy }}
{% if related_objects %}
{% blocktrans %} <i>{{ object }}</i> could not be deleted because it is still referenced by the following instances: {% endblocktrans %}
<br/>
<br/>
{% for o in related_objects %}
{% if protected_objects %}
<h5>{% trans 'Protected' %} <small class="text-muted">The object you are trying to delete is <b>protected</b> by the following references to it.</small></h5>
{% for o in protected_objects %}
{% class_name o.model as name %}
<h5>{{ name }}</h5>
<u>{{ name }}</u>
<ul>
{% for e in o %}
<li>
@ -36,14 +34,40 @@
</li>
{% endfor %}
</ul>
{% endfor %}
<br/>
{% endif %}
<button class="btn btn-success" type="submit" href="{{ success_url }}"><i
{% if cascading_objects %}
<h5>{% trans 'Cascade' %} <small class="text-muted">The object you are trying to delete is used by the following objects which will <b>also be deleted</b>.</small></h5>
{% for o in cascading_objects %}
{% class_name o.model as name %}
<u>{{ name }}</u>
<ul>
{% for e in o %}
<li>
<span class="badge badge-info">#{{ e.id }}</span> {{ e }}
</li>
{% endfor %}
</ul>
{% endfor %}
{% endif %}
{% if set_null_objects %}
<h5>{% trans 'Remove' %} <small class="text-muted">The object you are trying to delete is used by the following objects from which the reference will be removed.</small></h5>
{% for o in set_null_objects %}
{% class_name o.model as name %}
<u>{{ name }}</u>
<ul>
{% for e in o %}
<li>
<span class="badge badge-info">#{{ e.id }}</span> {{ e }}
</li>
{% endfor %}
</ul>
{% endfor %}
{% endif %}
<button class="btn btn-success" type="submit" href="{{ success_url }}" {% if protected_objects %}disabled{% endif %}><i
class="fas fa-trash-alt"></i> {% trans 'Confirm' %}</button>
<a href="javascript:history.back()" class="btn btn-danger"><i class="fas fa-undo-alt"></i> {% trans 'Cancel' %}
</a>

View File

@ -1,4 +1,5 @@
from django.contrib import messages
from django.db import models
from django.db.models import ProtectedError
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
@ -24,30 +25,36 @@ class RecipeDelete(GroupRequiredMixin, DeleteView):
success_url = reverse_lazy('index')
def delete(self, request, *args, **kwargs):
obj = self.get_object()
related_objects = []
for x in obj._meta.get_fields():
try:
related = x.related_model.objects.filter(**{x.field.name: obj})
if related.exists():
related_objects.append(related)
except AttributeError:
pass
if related_objects:
self.object = obj
return render(request, template_name=self.template_name, context=self.get_context_data(related_objects=related_objects))
self.object = self.get_object()
# TODO make this more generic so that all delete functions benefit from this
if self.get_context_data()['protected_objects']:
return render(request, template_name=self.template_name, context=self.get_context_data())
success_url = self.get_success_url()
obj.delete()
self.object.delete()
return HttpResponseRedirect(success_url)
def get_context_data(self, **kwargs):
context = super(RecipeDelete, self).get_context_data(**kwargs)
context['title'] = _("Recipe")
if 'related_objects' in kwargs:
context['related_objects'] = kwargs.pop('related_objects')
# TODO make this more generic so that all delete functions benefit from this
self.object = self.get_object()
context['protected_objects'] = []
context['cascading_objects'] = []
context['set_null_objects'] = []
for x in self.object._meta.get_fields():
try:
related = x.related_model.objects.filter(**{x.field.name: self.object})
if related.exists() and x.on_delete == models.PROTECT:
context['protected_objects'].append(related)
if related.exists() and x.on_delete == models.CASCADE:
context['cascading_objects'].append(related)
if related.exists() and x.on_delete == models.SET_NULL:
context['set_null_objects'].append(related)
except AttributeError:
pass
return context