pythondjangodjango-viewsdjango-urls

How do I correctly define the url in Django (error Page not found (404))


I am learning Django, and building the following project:

My project is es. I have 3 apps called event, items_dashboard and item. Each event has one items_dashboard, and zero or more items.

When the user is in /event/<event_id>/items_dashboard/index.html, there is a link to add a new item to event <event_id>. This opens a form /item/new/<event_id>. When I fill and submit this form, I get the following error:

Page not found (404)
Request Method: POST
Request URL:    http://127.0.0.1:8000/item/new/
Using the URLconf defined in event_site.urls, Django tried these URL patterns, in this order:

[name='index']
event/
item/ new/<int:event_id> [name='new']
item/ <int:pk>/ [name='detail']
item/ <int:pk>/delete [name='delete_item']
The current path, item/new/, didn’t match any of these.

Here is my code:

es/urls.py

urlpatterns = [
    path('', include('core.urls')),
    path('admin/', admin.site.urls),
    path('event/', include('event.urls', namespace="event")),
    path('item/', include('item.urls', namespace="item")),
    # path('', index, name='index')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

event/urls.py

app_name = 'event'

urlpatterns = [
    path('new/', views.new, name='new'),
    path('<int:pk>/', views.detail, name='detail'),
    path('<int:event_id>/items_dashboard/', include('items_dashboard.urls', namespace='items_dashboard')),
    path('<int:event_id>/item/', include('item.urls', namespace='item'))
]

item/urls.py

app_name = 'item'

urlpatterns = [
    # path('new/', views.new, name='new'),
    path('new/<int:event_id>', views.new, name='new'),
    path('<int:pk>/', views.detail, name='detail'),
]

item/views.py

@login_required()
def new(request, event_id):
    event = get_object_or_404(Event, pk=event_id)
    if request.method == "POST":
        form = NewItemForm(request.POST, request.FILES)
        if form.is_valid():
            item = form.save(commit=False)
            item.event = event
            item.creator = request.user
            item.save()
            return redirect('item:detail', pk=item.id)
    else:
        form = NewItemForm()
    
    return render(request, 'item/form.html', {
        'form': form,
        'title': 'Add new item'
    })

from the activity, I can see that when I submit the form, the new() function is called, and the correct event_id is provided

And finally, item/templates/item/form.html:

{% extends 'core/base.html' %}

{% block title %}{{ title }}{% endblock %}

{% block content %}
<h1 class="mb-6 text-3xl">{{ title }}</h1>
<form method="post" action="." enctype="multipart/form-data">
    {% csrf_token %}

    <div class="space-y-4">
        {{ form.as_p }}
    </div>

    {% if form.errors or form.non_field_errors %}
        <div class="mb-3 p-6 bg-red-100 rounded-xl">
            {% for field in form %}
                {{ field.errors }}
            {% endfor %}

            {{ form.non_field_errors }}
        </div>
    {% endif %}

    <button class="mt-6 py-4 px-8 text-lg bg-teal-500 hover:bg-teal-700 rounded-xl text-white">Create Item</button>
</form>
{% endblock %}

How do I correctly define the url for this scenario?

I tried solutions provided in similar questions, but they didn't work.


Solution

  • The issue is with html form action.

    <form method="post" action="." enctype="multipart/form-data">
    

    This line submits the form to root location

    to solve this issue just remove the action property. by default form submit the request to same url as shown in browser.

    modify the line like this.

    <form method="post" enctype="multipart/form-data">