Chandan Mahto
Chandan Mahto

Reputation: 147

View function is not being called after submitting form in django

I have made a simple form inside a html file whose path is www.site.com/posts/5. Whenever the form is submitted, it redirects back to the same page i.e www.site.com/posts/5 displaying a message given by user in the form.

However, whenever the form is submitted it doesn't call the foobar view.

The urls.py, views.py and html files are as follows:-

urls.py

urlpatterns = [
path('posts/<int:foo>',user_views.display, name="display",
path('posts/<int:foo>',user_views.foobar, name="makefoo"),
]

views.py

def foobar(request, foo):
    #do something

html file

<form name="fooform" action= "{% url 'makefoo' 5 %}" method = "post">
    {% csrf_token %}
    <input type="text" name="FOO_BODY" maxlength="300" required>
    <input type="submit" value="comment">
    <input type="reset" value="clear">
</form>

Edit : user_views is just from user import views as user_views

Upvotes: 3

Views: 1405

Answers (2)

b107
b107

Reputation: 88

As mentioned in the comment by @williem, you have two path() defined in the urls.py.

Always First matching route will be picked up from the url route table. So whenever r^'posts/' is requested it will call the display() from the user_views, so it will never go to foobar(). Either remove the route with display() or change the sequence. Also, I assume you imported the user_views.

Reference: https://docs.djangoproject.com/en/2.1/topics/http/urls/

Upvotes: 1

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476659

You can not attach two views to the same URL. The {% url ... %} template tag, only generates a URL for that path. But if there is a "url clash", then it is possible that the requests ends up in the other view.

You thus should define another URL, or encode the post logic in the display view. In case of a POST request, you can thus first take the necessary steps, and then for example return a redirect to the page, such that we can again render the page:

def display(request, foo):
    if request.method == 'POST':
        # do something
        return redirect(display, foo=foo)
    #do something else (original code)
    return HttpResponse(..)

This is the famous Post/Redirect/Get web development design pattern [wiki]. This is usually better than returning a HTTP response directly in the POST, since if the user performs a refresh, the POST will be performed a second time.

Upvotes: 2

Related Questions