Jon Koenig
Jon Koenig

Reputation: 63

Django Reverse for 'edit' with no arguments not found

I'm new to Django. I just laid out a new project to teach myself how routing works. I have a template that works like a 'detail view' to show information about an item in my database, and that template includes a button that should allow you to 'edit' this item. Clicking the button gives me:

NoReverseMatch at /4/edit
Reverse for 'edit' with no arguments not found. 1 pattern(s) tried: ['(?P<id>[^/]+)/edit$']

Here is the template. I am trying to call the dashboard app's 'edit' view and pass the current article's ID in as an argument.

{% extends 'dashboard/components/layout.html' %}

{% block content %}
<div id='detail-container'>
    <div class='detail-sidebar'>
        <a href='{% url 'dashboard:edit' id=article.id %}'>Edit</a>
    </div>

    <div class='article detail-article'>
        <h1 class='article-title'>{{ article.article_title }}</h1>
        <p class='article-body'>{{ article.article_body }}</p>
    </div>
</div>
{% endblock %}

Here is my urls.py file. To my understanding this should match the pattern named 'edit'

from django.urls import path
from . import views

app_name = 'dashboard'
urlpatterns = [
    path('', views.index, name='index'),
    path('new/', views.NewPost, name='new'),
    path('<id>/', views.ArticleDetailView, name='article'),
    path('<id>/edit', views.EditArticleView, name='edit'),
]

And finally, here is the view that the edit path should call. I'm aware that the logic is probably not right when it comes to rendering a form with data that already exists and all that, I'm really just trying to get this URL to work before I do some more reading on that.

@require_http_methods(["GET", "POST"])
def EditArticleView(request, id):
    if (request.method == 'GET'):
        a = Article.objects.get(pk=id)
        form = ArticleForm(instance=a) 
        context = {
            'form': form
        }
        return render(request, 'dashboard/edit.html', context)
    if (request.method == 'POST'):
        form = ArticleForm(request.POST)
        if (form.is_valid()):
            form.save()
            return redirect('dashboard:index')

I have the template included here as well:

{% extends 'dashboard/components/layout.html' %}

{% block content %}
{{ form.non_field_errors }}
<div id="new-form-container">
    <form action='{% url 'dashboard:edit' %}' method='post'>
        {% csrf_token %}
        {{form}}
        <button type='submit'>Submit</button>
    </form>
</div>
{% endblock %}

EDIT:

Fixed the issue by sending the ID back from the second template as described below, I then realized that I was not sending the ID in as part of the context when I first rendered the second template. After fixing both this works as expected. Thank you!

Upvotes: 1

Views: 1651

Answers (1)

Liza Amatya
Liza Amatya

Reputation: 141

You have missed to pass id in the second template's form action url.

<form action='{% url 'dashboard:edit' id=article.id %}' method='post'>

Upvotes: 1

Related Questions