Kirsty Russell
Kirsty Russell

Reputation: 15

Django URL error when using forms

I am fairly new to Django and I am totally stuck on what is causing this error. I have done lots of searching but to no avail! Any help would be super appreciated.

The actual form works fine but when I try and submit the input data I get the error:

Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:

^admin/
^$ [name='home']
^patientlist [name='patient_list']
^patientdetail/(?P<pk>\d+)/$ [name='patient_detail']
^add_patient/$ [name='add_patient']

The current URL, spirit3/add_patient/, didn't match any of these.

My urls.py in the mysite directory looks like:

from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include

urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('spirit3.urls')),
]

My urls.py in the app looks like:

from django.conf.urls import url
from . import views

urlpatterns = [
url(r'^$', views.home, name='home'), 
url(r'^patientlist', views.patient_list, name='patient_list'), 
url(r'^patientdetail/(?P<pk>\d+)/$', views.patient_detail, name='patient_detail'), 
url(r'^add_patient/$', views.add_patient, name='add_patient'),
]

The relevant part of views.py:

def add_patient(request):
    if request.method == 'POST':
       form = PatientForm(request.POST)
        if form.is_valid():
            form.save(commit=True)
            return redirect('home')
        else:
            print form.errors
    else:
        form = PatientForm()
    return render(request, 'spirit3/add_patient.html', {'form':form})

And the html looks like:

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

{% block content %}
<body>
    <h1> Add a Patient </h>
    <form action="/spirit3/add_patient/" method="post">
        {% csrf_token %}
        {{ form }}
        <input type="submit" value="Create Patient" />
    </form>
</body>
{% endblock %}

Thanks in advance! :)

Upvotes: 0

Views: 550

Answers (2)

bruno desthuilliers
bruno desthuilliers

Reputation: 77902

As pleasedontbelong mentionned, there's indeed no url matching "/spirit3/add_patient/" in your current url config. What you have in tour root urlconf is:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'', include('spirit3.urls')),
]

This means that urls with path starting with "/admin/" are routed to admin.site.urls, and all other are routed to spirit3.urls. Note that this does NOT in any way prefixes urls defined in spirit3.urls with '/spirit3/', so in your case, all of these urls:

urlpatterns = [
    url(r'^$', views.home, name='home'), 
    url(r'^patientlist', views.patient_list, name='patient_list'), 
    url(r'^patientdetail/(?P<pk>\d+)/$', views.patient_detail,      name='patient_detail'), 
   url(r'^add_patient/$', views.add_patient, name='add_patient'),
   ]

will be served directly under the root path "/" - ie, the add_patient view is served by "/add_patient/", not by "/spirit3/add_patient/".

If you want your spirit3 app's urls to be routed under "/spirit3/*", you have to specify this prefix in your root urlconf, ie:

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^spirit3/', include('spirit3.urls')),
]

Note that you can use any prefix, it's totally unrelated to your app name.

As a last note: never hardcode urls anywhere, django knows how to reverse an url from it's name (and args / kwargs if any). In a template you do this with the {% url %} templatetag, in code you use django.core.urlresolvers.reverse().

Upvotes: 0

pleasedontbelong
pleasedontbelong

Reputation: 20102

the form "action" attribute is wrong... seeing your urls configuration you dont have a /spirit3/add_patient/ url, I think It is /add_patient/

or you could just use a form tag without an "action" it will post to the current page:

<form role="form" method="post">
  {% csrf_token %}
  {{ form }}
  <input type="submit" value="Create Patient" />
</form>

Hope this helps

Upvotes: 2

Related Questions