When you visit /login/ in your browser, you're making a GET request — the server sends back a page with a form on it.
When you fill in the form and hit submit, the browser needs to know where to send the data. That's what the action attribute controls.
No action — Submit to the Same URL
If you don't write an action, the browser thinks:
"Send it back to the same URL I'm already on."
So if you're on /login/, the form data goes right back to /login/ — but this time as a POST request.
<form method="POST">
<input type="text" name="username">
<button type="submit">Login</button>
</form>
Your Django view handles both cases:
def login_view(request):
if request.method == 'POST':
# process the login credentials
else:
# show the empty form
Same URL /login/, same view — just handled differently depending on how the request arrived.
With action — Submit to a Different URL
Sometimes you want the form to send data somewhere else. For example, imagine a search bar sitting on your homepage /:
<form method="GET" action="/search/">
<input type="text" name="q" placeholder="Search...">
<button type="submit">Search</button>
</form>
You're on / but the form submits to /search/. A completely different view handles the results:
def search_view(request):
query = request.GET.get('q')
results = Post.objects.filter(title__icontains=query)
return render(request, 'search.html', {'results': results})
Quick Summary
| Scenario | What to write |
|---|---|
| Form submits to the same URL | Leave action empty |
| Form submits to a different URL | action="/that-url/" |
The rule of thumb: if your view handles both showing the form (GET) and processing it (POST) at the same URL, you don't need action. Simple as that.