Question

I followed this tutorial: Need a minimal Django file upload example

Obviously it works. But I want to be able to delete a file as well. Now even if I delete it manually from disc, it still appears on list, even after reconnecting to a server (why?)

I changed the list.html file by adding another form in the loop:

    <!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Minimal Django File Upload Example</title>   
    </head>

    <body>
        <!-- List of uploaded documents -->
        {% if documents %}
            <ul>
            {% for document in documents %}
                <li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}</a>
                {% if user.is_staff %}
                <form action="{% url 'delete' %}" method="post" enctype="multipart/form-data">
                {% csrf_token %}
                <input type="submit" value="Delete" />
                </form>
                {% endif %}
                </li>
            {% endfor %}
            </ul>
        {% else %}
            <p>No documents.</p>
        {% endif %}

        <!-- Upload form. Note enctype attribute! -->
        <form action="{% url 'list' %}" method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>{{ form.non_field_errors }}</p>
            <p>{{ form.docfile.label_tag }} {{ form.docfile.help_text }}</p>
            <p>
                {{ form.docfile.errors }}
                {{ form.docfile }}
            </p>
            <p><input type="submit" value="Upload" /></p>
        </form>

    </body>

</html> 

As you can see, I added Delete button in a form. By doing so, I have a button near each file. I added this to my views :

def delete(request):
    if request.method != 'POST':
        raise HTTP404
    else:
        docId = request.POST.get('docfile', None)

    if docId is not None:
        docToDel = Document.objects.get(pk=docId)
        docToDel.delete()

    form = DocumentForm(request.POST, request.FILES)
    documents = Document.objects.all()  
    return HttpResponseRedirect(reverse('myapp.views.list'))

But that does not do anything, just reloads the page. As I said, now I cannot even delete them manually. What am I doing wrong?

Was it helpful?

Solution

First of all file on disk and model in DB are different things. To delete file from disk and DB you may try this

from django.shortcuts import get_object_or_404

def delete(request):
    if request.method != 'POST':
        raise HTTP404

    docId = request.POST.get('docfile', None)
    docToDel = get_object_or_404(Document, pk = docId)
    docToDel.docfile.delete()
    docToDel.delete()

    return HttpResponseRedirect(reverse('myapp.views.list'))

Also you forgot to specify ID of Document to delete

<!-- List of uploaded documents -->
{% if documents %}
<ul>
    {% for document in documents %}
    <li><a href="{{ document.docfile.url }}">{{ document.docfile.name }}</a>
    {% if user.is_staff %}
        <form action="{% url 'delete' %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        <input type="hidden" name="docfile" value="{{ document.pk }}" />
        <input type="submit" value="Delete" />
        </form>
    {% endif %}
    </li>
    {% endfor %}
</ul>
{% else %}
<p>No documents.</p>
{% endif %}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top