0

Ive been struggling to come up with a solution to allow a logged in user in django to delete their own created model objects. Im testing on service objects (a service order they create with a ServiceForm(ModelForm). I have django-safedelete in use to preserve the deleted objects in django admin, but disappear for the user. I have this behavior working, but cannot actually delete the objects, tried a lot of permutations with 'id' in the delete_service url, pk=id in the view, a lot of different things but still get same type of error. (As noted below, on the service page, there is a context showing the model object's data in a panel, and in the lower right of the panel a delete button/modal popup which uses a context for the DeleteServiceForm function to delete the object. I heard you cant use more than one context per template but if not how is one to get around this problem?) Im using python3.5, django1.11, postgresql db, apache2, on ubuntu16.04 vm.

'''
#ERROR
Exception Type: NoReverseMatch at /dashboard/service/
Exception Value: Reverse for 'delete_service' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['dashboard/deleteservice/(?P<pk>\\d+)/$']

'''

# dashboard/urls.py
url(r'^dashboard/deleteservice/(?P<pk>\d+)/$', views.delete_service, name='delete_service'),
url(r'^dashboard/service/$', views.service, name='service'),

# dashboard models.py
    # django-safedelete model
from safedelete.config import *
from safedelete.models import SafeDeleteModel
from safedelete.managers import SafeDeleteManager

class MyModelManager(SafeDeleteManager):
    _safedelete_visibility = DELETED_INVISIBLE

# service model
class Service(SafeDeleteModel):
    _safedelete_policy = SOFT_DELETE_CASCADE

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True)

    service_type = models.ManyToManyField('ServiceType')
    description = models.TextField(blank=True)

    def __str__(self):
        return "Service Order for: {user}".format(user=self.user)

    objects = MyModelManager()

class ServiceType(models.Model):
    label = models.CharField(max_length=200, unique=True)

    def __str__(self):
        return self.label


# dashboard admin.py
class ServiceSDA(SafeDeleteAdmin):
    list_display = (highlight_deleted, '__str__', 'created_at') + SafeDeleteAdmin.list_display
    list_filter = ('user',) + SafeDeleteAdmin.list_filter
    def has_delete_permission(self, request, obj=Service):
        return True
admin.site.register(Service, ServiceSDA)


# dashboard forms.py
class NewServiceForm(forms.ModelForm):
    accept_tos = forms.BooleanField(required=True)

    class Meta:
        model = Service
        fields = '__all__'
        exclude = ('user', 'created_at',)
        widgets = {
        'description': Textarea(attrs={'cols': 65, 'rows': 3, 'class':'stucco'}),
        }

class DeleteServiceForm(forms.ModelForm):
    class Meta:
        model = Service
        fields = []


# dashboard views.py
@login_required
def service(request):
    service_list = Service.objects.all().filter(user=request.user).order_by('-created_at')
    context = {'service_list': service_list}
    return render(request, 'dashboard/service.html', context)

@login_required
def delete_service(request, pk):
    # some code to check if this object belongs to the logged in user
    if request.user.has_perm('dashboard.delete_Service'):
        service_to_delete = get_object_or_404(Service, pk=pk)

        if request.method == 'POST':
            form = DeleteServiceForm(request.POST, instance=service_to_delete)

            if form.is_valid():  # checks CSRF
                service_to_delete.delete()
                messages.warning(request, 'Success, your service order has been removed.')
                return redirect('service')

        else:
            form = DeleteServiceForm(instance=service_to_delete)

        return render(request, 'service', {'form': form, 'service_obj': service_to_delete})

    else:
        return http.Forbidden()


# dashboard / serviceblock.html  -  utilizes 2 contexts (1st is from service function, to show Service data in panel,
# 2nd is used in the modal popup, confirming deletion and using the DeleteServiceForm context 'service_obj': service_to_delete
'''
                                                        {% block services %}                                                            

                            {% for service in service_list %}

                    <div class="col-md-4">
                        <div class="panel panel-default text-left">      

                                <div class="panel-header matrix">
                                    <br>
        <h4 class="panel-title text-center" style="color: lime;"> &nbsp; SLD Service Order </h4> <br>
                                </div>

                                <div class="panel-body">
        <p>

            Created On: <span class="pull-right text-success"> {{ service.created_at }} </span> <hr>
            Service Type: <span class="pull-right text-success"> {% for type in service.service_type.all %} {{ type }} {% endfor %} </span> <hr>
            Description: <span class="pull-right text-success"> {{ service.description }} </span> 

        </p>                    
                                </div>

                                <div class="panel-footer matrix"> 
            <a href="#delservmodal" class="pull-right fa fa-times fa-2x" data-toggle="modal" aria-expanded="false" style="color: red;" title="Delete Service Order"></a> <br>
                                </div>

                        </div>
                    </div>


                            {% empty %}

                                            <div class="col-md-4 col-md-offset-3">
                             <br><br> <h4 class="text-center">No service orders opened yet.</h4>
                                            </div>
                        {% endfor %} 



<!-- Start Modal -->
<div id="delservmodal" class="modal fade">
  <div class="modal-dialog modal-sm" style="margin-top: 40vh;">
    <div class="modal-content">
        <div class="modal-body text-center">
  <h5 class="text-danger"> Please confirm to delete service order </h5> <hr>
                      <form method="post" action="{% url 'delete_service' pk=service_obj.pk %}">
                      {% csrf_token %}
<button type="submit" class="btn btn-sm" data-dismiss="modal"> Delete </button> Delete  
                        </form>
        </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->
<!-- End Modal -->                      

                                                        {% endblock %} 

'''
King Anu
  • 125
  • 2
  • 11

1 Answers1

0

After much struggle, abandoned writing a custom view that does not work, for the Generic DeleteView. best answer I found was here Python Django delete current object

King Anu
  • 125
  • 2
  • 11