Flask - Registration for new user doesn't work - Bad request - python

I am doing some app with Flask and I am working on registration now. I am working with SQL and not SQLAlchemy on this case (just to work with SQL a bit more)
Also using Flask-WTF for forms.
I successfully create database table:
class RegisterForm(Form):
name = StringField(
'Username',
validators=[DataRequired(), Length(min=4, max=25)]
)
email = StringField(
'Email',
validators=[DataRequired(), Length(min=6, max=40)]
)
password = PasswordField(
'Password',
validators=[DataRequired(), Length(min=6, max=40)])
confirm = PasswordField(
'Repeat Password',
validators=[DataRequired(), EqualTo('password', message='Passwords must match')]
)
In my views.py I have next for registration:
#app.route("/register/", methods=["GET", "POST"])
def register():
form = RegisterForm(request.form)
if request.method == "POST" and form.validate_on_submit():
name = request.form["name"]
email = request.form["email"]
password = request.form["password"]
g.db.connect_db()
g.db.execute("INSERT INTO users(name, email, password) VALUES (?,?,?)", (name, email, password))
g.db.commit()
g.db.close()
return render_template("register.html", form=form)
And my simple form:
<form action="/" method="post">
{{ form.csrf_token }}
<div class="form-group">
<label for="usernameInput">Username</label>
<input type="text" name="name" class="form-control" id="usernameInput">
</div>
<div class="form-group">
<label for="emailInput">Email</label>
<input type="email" name="email" class="form-control" id="emailInput">
</div>
<div class="form-group">
<label for="passwordInput">Password</label>
<input type="password" name="password" class="form-control" id="passwordInput">
</div>
<div class="form-group">
<label for="confirmInput">Confirm password</label>
<input type="password" name="confirm" class="form-control" id="confirmInput">
</div>
<button type="submit" class="btn btn-default btn-block">Register</button>
{% if error %}
<p class="error"><strong>Error:</strong> {{error}} </p>
{% endif %}
</form>
Now I have been trying, changing and fixing for 2 days and can't find a problem. When I enter all the data and click Register I get 400 Bad request.
Perhaps it something silly and I just can't see it.
If anyone can help, I would appriciate.
If need more info or code, let me know.
Thanks

Your form is posting to /, not /register/.
You haven't shown the route you defined for /, but presumably it does not accept POSTs.

Related

ValueError at /signup/ The given username must be set

so basically I have been building this blogging website and now I am stuck at this point of the Signup process, the whole work is done using django
views.py:
def handleSignup(request):
if request.method == 'POST':
# getting user parameters
username = request.POST.get('username')
fname = request.POST.get('fname')
lname = request.POST.get('lname')
email = request.POST.get('email')
pass1 = request.POST.get('pass1')
pass2 = request.POST.get('pass2')
# fname = request.POST['fname']
# lname = request.POST['lname']
# email = request.POST['email']
# pass1 = request.POST['pass1']
# pass2 = request.POST['pass2']
# creating users
myuser = User.objects.create_user(username = username, email = email, password = pass1)
myuser.first_name = fname
myuser.last_name = lname
myuser.save()
messages.success(request, 'your account have been successfully created!')
return redirect(request, 'home')
else:
return HttpResponse("error 404 not found")
form in base.html:
<form action="/signup/" method="post">
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username" placeholder="choose a unique username">
</div>
<div class="form-group">
<label for="fname">Firstname</label>
<input type="text" class="form-control" id="fname" placeholder="First Name">
</div>
<div class="form-group">
<label for="lname">Lastname</label>
<input type="text" class="form-control" id="lname" placeholder="Last Name">
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" class="form-control" id="email" placeholder="email#example.com">
</div>
<div class="form-group">
<label for="pass1">Choose Password</label>
<input type="password" class="form-control" id="pass1">
</div>
<div class="form-group">
<label for="pass2">Confirm password</label>
<input type="password" class="form-control" id="pass2">
</div>
{% csrf_token %}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
now I am getting this error:
ValueError at /signup/
The given username must be set
Request Method: POST
Request URL: http://127.0.0.1:8000/signup/
Django Version: 3.1
Exception Type: ValueError
Exception Value:
The given username must be set
Exception Location: C:\Users\jayant nigam\projects\practise\lib\site-packages\django\contrib\auth\models.py, line 135, in _create_user
Python Executable: C:\Users\jayant nigam\projects\practise\Scripts\python.exe
Python Version: 3.8.5
Python Path:
['C:\\Users\\jayant nigam\\projects\\everythingcs',
'C:\\Python38\\python38.zip',
'C:\\Python38\\DLLs',
'C:\\Python38\\lib',
'C:\\Python38',
'C:\\Users\\jayant nigam\\projects\\practise',
'C:\\Users\\jayant nigam\\projects\\practise\\lib\\site-packages']
Server time: Mon, 28 Sep 2020 16:21:27 +0000
as you guys can see in views.py I have already tried fname = request.POST['fname'] but then I was getting the MultiValueDictKeyError for which I searched on net and got a suggestion to use request.POST.get(' ') and after using that I am facing the above error
You have to add name to your input field in HTML:
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username" name="username" placeholder="choose a unique username">
</div>
You are not giving name in any of the input field. Server takes data from the form on the basis of name, but not id. So, provide name to each input tag in your form. And, you are good to go.

ValueError: The given username must be set. Error Occured Using Django for registering User

raise ValueError('The given username must be set') using django python
...
I have been trying to register a user using from django.contrib.auth.models import user
Views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth.models import User
# Create your views here.
def register(request):
if request.method == 'POST':
username = request.POST.get('username')
email = request.POST.get('email')
password1 = request.POST.get('password1')
password2 = request.POST.get('password2')
if password1 == password2:
if User.objects.filter(username = username).exists():
return redirect('register')
elif User.objects.filter(email = email).exists():
return redirect('register')
else:
user=User.objects.create_user(username = username,password =password1, email = email)
user.save()
return redirect('login')
else:
return redirect('/')
else:
return render(request, 'register.html')
def login(request):
return render(request, 'login.html')
register.html
<form method="POST" action="{% url 'register' %}">
{% csrf_token %}
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" id="username">
</div>
<div class="form-group">
<label for="password1">Password</label>
<input type="password" class="form-control" id="password1">
</div>
<div class="form-group">
<label for="password2">AGAIN Password</label>
<input type="password" class="form-control" id="password2">
</div>
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email" placeholder="name#example.com">
</div>
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="check">
<label class="form-check-label" for="check">Check me out</label>
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
user=User.objects.create_superuser(username = username,password =password1, email = email)
I want to know that why it is just sending that The given username is must be set but instead I have set super_user already. How to resolve this? It is not getting the username by POST method or is there any other mistake which I am ignoring?
add name attribute in your input tags, something like this:
...
<input type="text" class="form-control" id="username" name="username">
...
<input type="password" class="form-control" id="password1" name="password1">
...
<input type="password" class="form-control" id="password2" name="password2">
...
<input type="email" class="form-control" id="email" name="email" placeholder="name#example.com">
...
I think your problem here is the use of request.POST. If this is a form, you probably want to change this to be request.form wherever you're using request.POST. At the moment, your line request.POST.get("username") is returning None, so when you try to save the user it complains.
The Authentication system might be a little bit tricky if this is your first time doing it. I am going to link you with this project that i did a while ago; it has an authentication system with Django; it can help you out :
https://github.com/Nouamanezh909/BLog_repo.
--Go to Accounts, there you will find (
forms , view , everything you need.
)

Password not set for new django users

When a new user signs up for an account, the admin panel shows that a password has not been set for the user (despite saving it via views.py). Another strange thing I noticed is that the password is being saved to the email field in the database. The code appears fine. Not sure where I went wrong. Any help would be greatly appreciated.
sign up html template
{% if user.is_authenticated %}
<h2>currently logged in as {{ user.username }} </h2>
{% else %}
<h1 class="h5 text-center">Create Account</h1>
<h4>{{ error }}</h4>
<form method="POST">
{% csrf_token %}
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" name="username" autocomplete="username" placeholder="Username" id="id_username" required>
</div>
<div class="form-group">
<label for="password1">Password</label>
<input type="password" class="form-control" name="password1" placeholder="Password" autocomplete="new-password" required id="id_password1">
<small>Password must be at least 8 characters</small>
</div>
<div class="form-group">
<label for="password2">Confirm Password</label>
<input type="password" class="form-control" name="password2" placeholder="Confirm Password" autocomplete="new-password" required id="id_password2">
</div>
<ul>
<li>Your password can’t be too similar to your other personal information.</li>
<li>Your password must contain at least 8 characters.</li>
<li>Your password can’t be a commonly used password.</li>
<li>Your password can’t be entirely numeric.</li>
</ul>
<!-- <div class="form-group">
<div class="custom-control custom-checkbox text-small">
<input type="checkbox" class="custom-control-input" id="sign-up-agree">
<label class="custom-control-label" for="sign-up-agree">I agree to the <a target="_blank" href="utility-legal-terms.html">Terms & Conditions</a>
</label>
</div>
</div> -->
<button class="btn btn-primary btn-block" type="submit">Create Account</button>
</form>
views.py
def signup(request):
if request.method == 'GET':
return render(request, 'events/signup.html', {'form': UserCreationForm()})
else:
# Create new user and profile
if request.POST['password1'] == request.POST['password2']:
try:
print(request.POST['password1'])
print(request.POST['password2'])
user = User.objects.create_user(request.POST['username'], request.POST['password1'])
user.save()
login(request, user)
return redirect('home')
except IntegrityError:
return render(request, 'events/signup.html', {'form': UserCreationForm(), 'error':'Username has already been taken. Please use a different name.'})
else:
# Tell the user the passwords don't match
return render(request, 'events/signup.html', {'form': UserCreationForm(), 'error':'Passwords did not match'})
There's no mention of "email" anywhere in the code but for some reason the password gets saved as email and the actual password isn't getting set.
You need to set password explicitly, or send it in the third param, second param of create_user method is email, thats why password is being set as email.
reference to set_password method
reference to create_user method
You need something like this.
user = User.objects.create_user(username=request.POST['username'])
user.set_password('new password')
user.save()
Your code:
user = User.objects.create_user(request.POST['username'], request.POST['password1'])
user.save()
See the the docs:
create_user(username, email=None, password=None, **extra_fields)
So, oops, you send the password as second argument and it is interpreted as being the email address.
create_user(username=request.POST['username'], password=request.POST['password1'])
Should work.

Django doesn't read form

I have form:
<form id="contact-form" class="contact__form" method="POST" action="{% url 'backcall' %}">
{% csrf_token %}
<span class="text-color">Send letter</span>
<div class="form-group">
<input name="name" type="text" class="form-control" placeholder="Name">
</div>
<div class="form-group">
<input type="tel" name="phone" class="form-control" placeholder="Phone (+380)" pattern="[\+][3][8][0]\d{9}" minlength="13" maxlength="13" />
</div>
<div class="form-group">
<input name="email" type="email" class="form-control" placeholder="Email">
</div>
<div class="form-group-2 mb-4">
<textarea name="message" class="form-control" rows="4" placeholder="Your letter"></textarea>
</div>
<button class="btn btn-main" name="submit" type="submit">Send</button>
</form>
views.py:
def backcall(request):
backcall = BackCall(name = request.POST['name'], phone = request.POST['phone'], email=request.POST['email'] , message = request.POST['message'])
backcall.save()
return redirect('thanks')
models.py
class BackCall(models.Model):
name = models.CharField(max_length=50)
phone = models.CharField(max_length=13)
email = models.EmailField()
message = models.TextField(default=None)
datetime = models.DateTimeField(auto_now_add=True)
When I fill out the form and submit nothing happens. When I follow the link 'backcall/' I get an error.
What the problem can be connected with and how to fix it?
Please, search more, exist the solution
Use the MultiValueDict's get method. This is also present on
standard dicts and is a way to fetch a value while providing a default
if it does not exist.
def backcall(request):
backcall = BackCall(name = request.POST.get('name'), phone = request.POST.get('phone'), email=request.POST.get('email') , message = request.POST.get('message'))
backcall.save()
return redirect('thanks')
You should check whether or not the record exists in your database, I think, a quick example would be:
def backcall(request):
obj, created = BackCall.objects.get_or_create(email=request.POST.get('email'),
defaults={'phone': request.POST.get('phone'),
'name': request.POST.get('name'),
'message': request.POST.get('message')}
if created:
return redirect('thanks')
return ...

Flask Python submit button

I am trying to create a page to register users but the submit button in my bootstrap form isn't working. When I hit the submit button, I get a bad request error. Here is the code in my python file:
#app.route('/register', methods=['GET', 'POST'])
def register():
if request.method == 'POST':
if not request.form['username']:
error = 'You have to enter a username'
elif not request.form['email'] or '#' not in request.form['email']:
error = 'You have to enter a valid email address'
elif not request.form['password']:
error = 'You have to enter a password'
elif get_user_id(request.form['username']) is not None:
error = 'The username is already taken'
else:
print(request.form['username'])
db = get_db()
db.execute('INSERT INTO user (username, email, pw_hash) VALUES (?, ?, ?)',
[request.form['username'], request.form['email'],
generate_password_hash(request.form['password'])])
db.commit()
flash('You were successfully registered and can login now')
return render_template('control.html')
return render_template('register.html')
also i have a html file register.html:
{% extends 'layout.html' %}
{% block title %}Sign-up{% endblock title %}
{% block body %}
<div class="container">
<form class="form-register" role="form" method="post" action="{{ url_for('register') }}">
<h2 class="form-register-heading">Please sign up</h2>
<label for="username" class="sr-only">Username</label>
<input type="username" id="inputUsername" class="form-control" value="{{ request.form.username }}" placeholder="Username" required autofocus>
<label for="email" class="sr-only">Email address</label>
<input type="email" id="inputEmail" class="form-control" value="{{ request.form.email }}" placeholder="Email address" required autofocus>
<label for="password" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required >
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign up</button>
</form>
</div>
{% endblock body %}
I can't find where I did it wrong, I'm new to python and flask!
Your input fields have no name attribute. This will cause all of your checks to result in KeyErrors. The first step is to add the attribute to each input.
<input name="username" type="text" id="inputUsername" class="form-control" value="{{ request.form.username }}" placeholder="Username" required autofocus>
Note that I also checked the type attribute as there is no username type. email and password are valid values, email being added in HTML5.
The next step will be to change how you check for the fields. If you only care about the presence of the field, in is the way to go.
if 'username' not in request.form:
If, however, you also want a truty value, the get method is what you want.
if not request.form.get('username'):

Categories

Resources