NoReverseMatch and Post Token in the URL in Class Based Views

2

I'm trying to do a simple "edit and delete" with views based on Django classes.

The problem is that I'm getting these errors with UpdateView and DeleteView . One occurs when I want to redirect to its DetailView after the update and the other occurs when the form's token passes through the url and does not redirect me to the main page of the application.

urls.py :

from django.conf.urls import url

from django.conf import settings
from django.conf.urls.static import static

from .views import PinList, PinCreate, PinDetail, PinDelete, PinEdit

app_name = 'Pin'
urlpatterns = [
    url(r'^$', PinList.as_view(), name='pin_list'),
    url(r'^pin/add/$', PinCreate.as_view(), name='pin_add'),
    url(r'^pin/(?P<pk>\d+)/$', PinDetail.as_view(), name='pin_detail'),
    url(r'^pin/delete/(?P<pk>\d+)/$', PinDelete.as_view(), name='pin_delete'),
    url(r'^pin/edit/(?P<pk>\d+)/$', PinEdit.as_view(), name='pin_edit'),

] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

views.py:

from django.shortcuts import render, redirect
from django.urls import reverse_lazy
from django.views.generic import ListView, CreateView, DetailView, DeleteView, UpdateView

from .models import Pin
from .forms import PinCreateForm

# Create your views here.
class PinList(ListView):
    model = Pin

class PinDetail(DetailView):
    model = Pin

class PinCreate(CreateView):
    model = Pin
    form_class = PinCreateForm
    template_name = 'pins/pin_create.html'

    def form_valid(self, form):
        form.instance.user = self.request.user
        form.save()
        return redirect('/')

class PinDelete(DeleteView):
    model = Pin
    success_url = reverse_lazy('Pin:pin_list')

class PinEdit(UpdateView):
    model = Pin
    form_class = PinCreateForm
    success_url = reverse_lazy('Pin:pin_detail')
    template_name = 'pins/pin_edit.html'

pin_detail.html :

{% extends "base.html" %}

{% block content %}
    <section class="Pin">
            <article class="Pin-container">
                <figure class="Pin-item"></figure>
                    <img src="{{ pin.image.url }}" alt="">
                    <figcaption class="Pin-user"> 
                        {{ pin.user.username}}
                        {% if user.is_authenticated %}
                            <a href="{% url "Pin:pin_edit" pin.id %}">Edit</a>
                            <a href="{% url "Pin:pin_delete" pin.id %}">Delete</a>
                        {% endif %}
                    </figcaption>
                </figure>
            </article>
    </section>

{% endblock content %}

pin_confirm_delete.html:

{% extends "base.html" %}

{% block content %}

    <form action="POST" action="/">
        {% csrf_token %}
        <p>Are  you sure you want to delete {{ object.title }}?
        <input type="submit" value="Confirm">
    </form>

{% endblock content %}

After confirming, my url changes to:

  

link

What it causes:

  

404 not found

pin_edit.html:

{% extends "base.html" %}

{% block content %}

<h1>Add Pin</h1>

<form enctype="multipart/form-data" action="" method="POST">
    {% csrf_token %}
    {{ form.as_p }}
    <input type="submit">
</form>

{% endblock content %}

With this, after giving it to send, I get the following error:

  

Reverse for 'pin_detail' with no arguments not found. 1 pattern (s) tried: ['pin / (? P \ d +) / $']

If someone can help me with this, I'll appreciate it.

    
asked by ikenshu 30.08.2017 в 22:53
source

1 answer

3

The first error is simple, if you throw a 404, is that the page does not exist, and you have to go to verify that is wrong with the urls. In your case you have the form in html of the following form:

<form action="POST" action="/">

Which says to send the form information to endpoint "POST" , you must change it to:

<form method="POST" action="/">

That's how you specify the HTTP method used by the form. Now, the ideal is that if you are getting that form from the GET of the view that eliminates, I would recommend you just use action="." otherwise change it to action="/pin/delete/{{ object.id }}" where id is the id of the pin.

And for the second error, it's something that class-based views have, if you pass a url, you should know how to solve it, so I recommend you overwrite the get_success_url method in the following way:

class PinEdit(UpdateView):
    model = Pin
    form_class = PinCreateForm
    success_url = reverse_lazy('Pin:pin_detail')
    template_name = 'pins/pin_edit.html'

    def get_success_url(self):
        return reverse_lazy('Pin:pin_detail', args=(self.object.id, ))

I hope I have helped you, any doubt comments:)

    
answered by 30.08.2017 / 23:13
source