Django: Template Form action not redirecting - html

My Form action is not redirecting to the passed view. I am calling simple_upload view method from login_form.html form action. Instead, upon clicking the login button, it stays on the same page. Below is my code:
urls.py:
from django.conf.urls import url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
from uploads.core import views
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', views.login_form, name='login_form'),
url(r'^upload/', views.simple_upload, name='simple_upload'),
url(r'^drop_down/$', views.drop_down, name='drop_down'),
url(r'^visualize_view/$', views.visualize_view, name='visualize_view'),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.AKASH_ROOT)
login_form.html:
{% block content %}
<button onclick="document.getElementById('id01').style.display='block'" style="width:auto;">Login</button>
<div id="id01" class="modal">
<form class="modal-content animate" action="{% url 'simple_upload' %}" method="get">
{% csrf_token %}
<div class="imgcontainer">
<span class="close" title="Close Modal">×</span>
<img src="https://www.w3schools.com/howto/img_avatar2.png" alt="Avatar" class="avatar">
</div>
<div class="container">
<label for="uname"><b>Username</b></label>
<input type="text" placeholder="Enter Username" name="uname" required>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="psw" required>
<button type="submit">Login</button>
<label>
<input type="checkbox" checked="checked" name="remember"> Remember me
</label>
</div>
<div class="container" style="background-color:#f1f1f1">
<button type="button" class="cancelbtn">Cancel</button>
<span class="psw">Forgot password?</span>
</div>
</form>
</div>
<script>
// Get the modal
var modal = document.getElementById('id01');
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
</script>
{% endblock %}
views.py:
from django.http import HttpResponse
from django.shortcuts import render, redirect
from django.core.files.storage import FileSystemStorage
from .models import Document
from .forms import ExpenseForm
def login_form(request):
return render(request, 'core/login_form.html')
def simple_upload(request):
return HttpResponse("Hello World")
Project hierarchy:

Your home URL pattern is not terminated, so it matches every path. It should be:
url(r'^$', views.login_form, name='login_form'),

It's not good form logic. Forms have valid and invalid actions. If your form is valid you redirect to new (success) page your user, but if not you render same (login) page. But firstly you should give a name your login page like below or use Django's inherit auth urls:
url(r'^login', views.login_form, name='login_form'),
It's my url paths:
from django.contrib import admin
from django.urls import path, include
from . import views
app_name = "user"
urlpatterns = [
path('sign_up/', views.sign_up, name="sign_up"),
path('account_activation_sent/', views.account_activation_sent, name='account_activation_sent'),
path('activate/<uidb64>/<token>/', views.activate, name="activate"),
path('login/', views.login_user, name="login"),
path('logout/', views.logout_user, name="logout"),
path('password_reset/', views.password_reset, name="password_reset"),
path('password_reset/done/', views.password_reset_done, name="password_reset_done"),
path('password_reset/<uidb64>/<token>/', views.password_reset_confirm, name="password_reset_confirm"),
path('password_reset/complete/', views.password_reset_complete, name="password_reset_complete"),
path('profile/<slug:slug>/', views.profile, name="profile"),
]
I wanna show you my simple login function and you will understand:
def login_user(request):
if request.user.is_authenticated:
return redirect("index")
else:
form = LoginForm(request.POST or None)
context = {
"form": form
}
go_to = request.POST.get('next', '/')
print(go_to)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
user = authenticate(username=username, password=password)
if user is None:
messages.error(request, "Username or password is incorrect! Try again.")
return render(request, "auths/login.html", context)
messages.success(request, "Login successful! Welcome bro.")
login(request, user)
go_to = request.POST.get('next', '/')
if go_to:
go_to = request.POST.get(
'next')
return redirect(go_to)
else:
return redirect("index")
return render(request, "auths/login.html", context)
I use Django's form and It's easy but you can use your custom form in your template. My form is like this:
class LoginForm(forms.Form):
username = forms.CharField(label="Username")
password = forms.CharField(label="Password", widget=forms.PasswordInput)
def __init__(self, *args, **kwargs):
super(LoginForm, self).__init__(*args, **kwargs)
self.fields['username'].label = ''
self.fields['password'].label = ''
class Meta:
model = User
fields = ('username', 'password' )
I hope It will help you.

Related

Django override django.contrib.auth login process

views.py
from django.contrib import messages
from django.http import HttpResponse
from django.contrib.auth import authenticate, login
from django.contrib.auth.views import LoginView
from django.shortcuts import render
def index(request):
return render(request, 'index.html')
def templates(request):
return render(request, 'templates.html')
def information(request):
return render(request, 'information.html')
def custom_login(request):
if request.POST:
username = request.POST['username']
password = request.POST['password']
user = authenticate(username = username, password = password)
print("work")
if user is not None:
messages.success(request, 'Success')
login(request, user)
return HttpResponse('login')
#logout(request)
else:
messages.error(request, 'Invalid username or password')
print("error")
return HttpResponse('wrong username or password')
class CustomLoginView(LoginView):
print("check")
def form_valid(self):
custom_login(self.request)
urls.py
from django.contrib import admin
from django.urls import path, include
from ArtisticCode import views
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/login/', views.CustomLoginView.as_view(), name='login'),
path('accounts/', include('django.contrib.auth.urls')),
path('', views.index, name = 'index'),
path('templates/', views.templates, name = 'templates'),
path('information/', views.information, name = 'information'),
]
accounts/login.html
<form method="post" class="login">
{% csrf_token %}
<div class="login_input">
<img src="{% static 'img/bx_img1.png' %}" alt="image"/>
<input type="text" placeholder="Username" name="username" required/>
</div>
<div class="login_input">
<img src="{% static 'img/bx_img1.png' %}" alt="image"/>
<input type="password" placeholder="Password" name="password" required/>
</div>
<input type="submit" value="Send message"/>
{% if messages %}
{% for message in messages %}
<strong style="color:white;">{{ message }}</strong>
{% endfor %}
{% endif %}
</form>
The idea is to display a message in case of a wrong password, but I can't catch the post method correctly. From what I did past few days to try to make this, I found that I need to override the login. I think the function form_valid is the one that I need to override so I can handle the post method
setting.py
INSTALLED_APPS = [
'django.contrib.auth',
'django.contrib.messages',
]
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
]
The solution to the problem is to do everything yourself without using the ready-made functions, because the password and the name go to the same place, whether you write it yourself or use ready code. The idea from the beginning was that if I use the ready forms such as form.as _p I can't laugh at the style then there was no way to put notification for a wrong password from there I came to the conclusion that is writing everything yourself is best.
changes:
urls.py
from django.contrib import admin
from django.urls import path
from ArtisticCode import views
urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/login/', views.login, name='login'),
path('', views.index, name = 'index'),
path('templates/', views.templates, name = 'templates'),
path('information/', views.information, name = 'information'),
]
views.py
from django.contrib import messages
from django.contrib.auth import authenticate, login
from django.shortcuts import render
def index(request):
return render(request, 'index.html')
def templates(request):
return render(request, 'templates.html')
def information(request):
return render(request, 'information.html')
def login(request):
if request.POST:
username = request.POST['username']
password = request.POST['password']
user = authenticate(username = username, password = password)
if user is not None:
messages.success(request, 'Success')
#login ...
else:
messages.error(request, 'Invalid username or password')
return render(request, 'registration/login.html')

Django 1.10 - Issue passing value from Template to View

I am having an issue when it cmoes to passing variables from templates to views. Even though I am able to pass variables from view to template, I canot seem to get it right. I have looked at similar questions here.
Following the Django docs I created a forms.py script as follows:
forms.py
GNU nano 2.7.4 File: forms.py
from django import forms
class TactForm(forms.Form):
tacttime = forms.CharField(label='Tact Time', max_length=100)
Updated View
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
from django.http import HttpResponse
from lineoee.models import Lineoee31
from .forms import TactForm
def details(request):
if request.method == 'POST':
form = TactForm(request.POST)
print(form)
else:
form = TactForm()
context = {'form' : form}
return render(request, 'linedetails/index.html',context)
Updated Template
<form method="POST" action="{% url 'details' %}">
{% csrf_token %}
{{ form.as_p }}
<label for="tacttime">Tact Time: </label>
<input id="tacttime" type="text" name="tacttime" value ="60">
<input type="submit" value="OK">
<form>
Updated URLS
from django.conf.urls import url
from django.contrib import admin
from lineoee.views import index
from lineoee.views import details
urlpatterns = [
url(r'lineoee/$', index, name='index'),
url(r'linedetails/', details, name='details'),
]
Still, no errors and no values passed to the view.
EDIT
I am now getting some data on pressing the OK button, however it is not what I was expecting. I want to be able to retrieve the text entered into the input field. How can I do this?
"POST /linedetails/ HTTP/1.1" 200 24580
<tr><th><label for="id_tacttime">Tact Time:</label></th><td><input
type="text" name="tacttime" value="60" required id="id_tacttime"
maxlength="100" /></td></tr>
Template
<div style="text-align:center;">
<form method="POST" action="{% url 'details' %}">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="adsfadsfas">
</form>
</div>
Views (EDITED)
Whatever the name you use in your input on your HTML template, that's the key you're gonna use to get what comes in the request.POST. That's why you'd like to use {{ form.field }} in the template so you know beforehand the name of the fields you're expecting to come in the request.POST
def details(request):
if request.method == 'POST':
print(request.POST)
print(request.POST.get('tacttime')
form = TactForm(request.POST)
print(form)
else:
form = TactForm()
return render(request, 'linedetails/index.html', context)
URLS
from django.conf.urls import url
from django.contrib import admin
from lineoee.views import index
from lineoee.views import details
urlpatterns = [
url(r'lineoee/$', index, name='index'),
url(r'linedetails/', details, name='details'),
]
def details(request):
if request.method == 'POST':
var = request.POST['textfield']
print(var)

form fields a not showing up on html page django

This is my template which I am using in the login page but the problem is fields are not showing up .I want to use mdbootstrap on the page.i have searched it on many websites but did't got a solution and every one was using the same thing to use the form is the something I am missing in my code?
<form action="{% url 'log_in' %}" method="POST">
{% csrf_token %}
<div class="md-form">
<i class="fa fa-envelope prefix"></i>
{{ form.username }}
{{ form.username.label_tag }}
</div>
<div style="padding:5px"></div>
<div class="md-form" >
<i class="fa fa-lock prefix"></i>
{{ form.password.label_tag }}
{{ form.password }}
</div>
{% if requset.GET.next %}
<input type="hidden" name="next" value="{{ request.GET.next }}">
{% endif %}
<button type='submit' class="btn info-color ">log in</button>
</form>
and forms.py
from django.contrib.auth.forms import AuthenticationForm
from django import forms
class LoginForm(AuthenticationForm):
username = forms.CharField(label="Username", max_length=30,
widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'username'}))
password = forms.CharField(label="Password", max_length=30,
widget=forms.PasswordInput(attrs={'class': 'form-control', 'name': 'password'}))
my view function is
def log_in(request):
if request.user.is_authenticated:
return render(request,'registration/userhome.html')
elif request.POST:
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user.is_active:
login(request, user)
return render(request,"registration/userhome.html")
else :
return HttpResponse("Invalid login details supplied.")
views login_view()
def login_view(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
pass # does nothing, just trigger the validation
else:
form = LoginForm()
return render(request,"registration/login.html",{'form':form})
I have not even rendered the login page but still they are working and the part of form feilds are missing in it
my urls.py file
from django.urls import path
from . import views
from django.contrib.auth.views import LoginView
urlpatterns =[
path("",views.index,name='index'),
path("userhome/",views.userhome,name='userhome'),
path("quiz/", views.quiz, name='quiz'),
path("signup/", views.sign_up,name='sign_up'),
path("login/", views.login_view, name='login'),
path("login/", views.log_in, name='log_in'),
path("index", views.log_out,name='log_out'),
path("rules/",views.rules,name='rules'),
]
You must have a view like this :
def myView(request):
if request.method == 'POST':
form = LoginForm(request.POST)
if form.is_valid():
pass # does nothing, just trigger the validation
else:
form = LoginForm()
return render(request, 'myTemplate.html', {'form': form})

form field not showing (django 1.7)

The form field (text area) is not showing in my django template. I can figure out where the problem is.
Views.py
class Profile(View):
"""User Profile page reachable from /user/<username> URL"""
def get(self, request, username):
params = dict()
user = User.objects.get(username=username)
tweets = Tweet.objects.filter(user=user)
params["tweets"] = tweets
params["user"] = user
return render(request, 'profile.html', params)
class PostTweet(View):
"""Tweet Post form available on page /user/<username> URL"""
def post(self, request, username):
if request.method == 'GET':
form = TweettForm()
else:
form = TweetForm(self.request.POST)
if form.is_valid():
user = User.objects.get(username=username)
tweet = Tweet(text=form.cleaned_data['text'], user=user, country=form.cleaned_data['country'])
tweet.save()
words = form.cleaned_data['text'].split(" ")
for word in words:
if word[0] == "#":
hashtag, created = HashTag.objects.get_or_create(name=word[1:])
hashtag.tweet.add(tweet)
return HttpResponseRedirect('/user/'+username)
return render(request, 'profile.html', {'form': form})
forms.py
from django import forms
class TweetForm(forms.Form):
text = forms.CharField(widget=forms.Textarea(attrs={'rows': 1, 'cols':85}), max_length=160)
country = forms.CharField(widget=forms.HiddenInput())
profile.html
{% extends "base.html" %}
{% block content %}
<div class="row clearfix">
<div class="col-md-12 column">
<form method="post" action="post/">{% csrf_token %}
<div class="col-md-8 col-md-offset-2 fieldWrapper">
{{ form.text.errors }}
{{ form.text }}
</div>
{{ form.country.as_hidden }}
<div>
<input type="submit" value="post">
</div>
</form>
</div>
urls.py
from django.conf.urls import patterns, include, url
from django.contrib import admin
from tweets.views import Index, Profile, PostTweet
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', Index.as_view()),
url(r'^user/(\w+)/$', Profile.as_view()),
url(r'^admin/', include(admin.site.urls)),
url(r'^user/(\w+)/post/$', PostTweet.as_view())
)
Only the submit (post) button shows on the on when rendered in the browser. The text are is not there
You get nothing since you are not passing the form to the template. Write get function in PostTweet view and include form = TweetForm() in it as a param passed to the template.

Django and the POST request: unexpected behaviour with a form

urls.py
from django.conf.urls.defaults import patterns, include, url
import myproject.views
urlpatterns = patterns('', (r'^$', myproject.views.home), (r'^login$', apolla.views.login))
views.py
import django.http
import django.template
import django.shortcuts
def home(request):
return django.http.HttpResponse("Welcome home!")
def login(request):
un = request.POST.get('username')
pa = request.POST.get('password')
di = {'unam': un, 'pass': pa}
if un and pa:
di['act'] = "/"
else:
di['act'] = "/login"
return django.shortcuts.render_to_response('login.html', di,
context_instance=django.template.RequestContext(request))
# Why does this code not send me immediately to "/" with
# username and password filled in?
login.html
<html>
<head>
</head>
<body>
<form name="input" method="post" action="{{ act }}">
{% csrf_token %}
Username:
<input type="text" name="username"><br>
Password:
<input type="password" name="password"><br>
<input id="su" type="submit" value="Submit"><br>
</form>
</body>
</html>
When I run the development server and go to localhost:8000/login and fill in a username and password and push the submit button I am not sent to localhost:8000/ as I expected from my login function in views.py, I just return to localhost:8000/login. But when I fill in any field and submit for the second time I get directed to localhost:8000.
I also used print un and print pa to see if the post caught the data from the username and password fields and it did from the first time, so why am I not being directed to localhost:8000/login from the first submit with both username and password fields filled in?
You can add redirects to your view by:
from django.http import HttpResponseRedirect
def foo_view(request):
# ...
return HttpResponseRedirect('/')