Delete method does not work

Asked

Viewed 37 times

-3

I am creating a PDF upload application (for educational purposes), I have a page that lists all the books, one to upload, and another that shows the information. I have two methods that use the object id in my view:

def book_detail(request, pk):
  book = Book.objects.get(pk=pk)
  context = {
    'book': book,
  }
  return render(request, 'book_detail.html', context)


def delete_book(request, pk):
  if request.method == 'POST':
     book = Book.objects.get(pk=pk)
     book.delete()
  return redirect('book_list')

This is my main page, where I list all the books:

inserir a descrição da imagem aqui

Everything worked well, until I decided to implement this method to delete, when I try to delete the object I am redirected to detail page.

{% extends 'base.html' %}

{% block content %}
    <h2 class="card-title">Book List</h2>
    <p>
        <a href="{% url 'upload_book' %}" class="btn btn-primary">Upload Book</a>
    </p>

    <table class="table mb-0">
        <thead>
            <tr>
                <th>Cover</th>
                <th>Title</th>
                <th>Author</th>
                <th>Details</th>
                <th>Download</th>
            </tr>
        </thead>
        <tbody>
            {% for book in books %} 
                <tr>
                    <td>
                        {% if book.cover %} 
                            <img src="{{ book.cover.url }}" alt="{{ book.title }}" width="100px">
                        {% else %}
                            <span class="text-muted">No cover</span>
                        {% endif %}
                    </td>
                    <td>{{ book.title }}</td>
                    <td>{{ book.author }}</td>
                    <td>
                        <a href="{% url 'book_detail' book.pk %}" class="btn btn-info btn-sm">Info</a>
                    </td>
                    <td>
                        <a href="{{ book.pdf.url }}" class="btn btn-primary btn-sm" target="_blank">Download PDF</a>
                    </td>
                    <td>
                        <form method="post" action="{% url 'delete_book' book.pk %}">
                            {% csrf_token %}
                            <button type="submit" class="btn btn-danger btn-sm">Delete</button>
                        </form>
                    </td>
                </tr>
            {% endfor %}
           
        </tbody>
    </table>
{% endblock %}

Here is the.py url:

urlpatterns = [
  path('', views.Home.as_view(), name='home'),
  path('books/', views.book_list, name='book_list'),
  path('books/upload', views.upload_book, name='upload_book'),
  path('books/<int:pk>/', views.book_detail, name="book_detail"),
  path('books/<int:pk>/', views.delete_book, name='delete_book'),
]

1 answer

-1

You have in your file urls.py two urls pointing to different methods. It will always fall on the first if you pass books/<int:pk>/. I believe that the best would be to do something like below:

py.

urlpatterns = [
  path('', views.Home.as_view(), name='home'),
  path('books/', views.book_list, name='book_list'),
  path('books/upload', views.upload_book, name='upload_book'),
  path('books/<int:pk>/', views.handle_book_request, name="handle_book"),  # a mudança foi aqui !!!
]

py views.

def handle_book_request(request, pk):
    if request.method == 'GET':
        book_detail(request, pk)
    elif request.method == 'PUT':
        insert_book(request, pk)
    elif request.method == 'DELETE':
        delete_book(request, pk)

From this idea it is simple to create the methods.

  • For those who voted negative, could you say why? So I improve my answer.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.