I created a password reset system through email using django, but when I am at the password page, if I enter the password and confirmation right, it doesn't do anything just reloads the page and seems to throw in error in form.errors, but it shows this field is required (error) even though I filled it out.
In addition, how do you make it so only one email can be assigned to a user. So when registering or changing your info, the same email can't be used with two accounts.
Here is the code to my password reset page:
{% extends 'base.html' %}
{% block head %}
<link href="\static\accounts\css\forms.css" rel="stylesheet">
<script src="\static\registration\js\emailvariable.js"></script>
{% endblock %}
{% block body %}
{% if validlink %}
<h3 style="text-align: center">Change password</h3>
<form id="login-form" method="post">
{% csrf_token %}
<input placeholder="Password" id="id_password" name="password"
type="password" class="form-control">
<input placeholder="Confirm Password" id="id_password2" name="password2"
type="password" class="form-control">
<div style="text-align:center;">
<button type="submit" class="btn btn-outline-dark centerbutton">Change password</button>
</div>
{% if form.errors %}
<p class=" label label-danger">
<div style="text-align: center">
{{ error | escape }}
</div>
</p>
{% endif %}
</form>
{% else %}
<p>
The password reset link was invalid, possibly because it has already been used.
Please request a new password reset.
</p>
{% endif %}
{% endblock %}
I am not sure about your first question, but I can answer the 2nd.
class SignUpForm(UserCreationForm):
def clean_email(self):
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
if email and User.objects.filter(email=email).exclude(username=username).exists():
raise forms.ValidationError(u'Email addresses must be unique.')
return email
Put something like that in the forms.py where you have the registration form.
for the email portion of your question:
views.py
email = self.cleaned_data.get('email')
foo = User.objects.filter(email=email)
if foo:
return error
else:
***carry forth with saving the new user***
the 'if foo' will see if a user exists in the db with the email address given. If so, return error. If not carry forth with code.
I solved the form problem.
You need to change:
<input placeholder="Password" id="id_password" name="password" type="password" class="form-control">
<input placeholder="Confirm Password" id="id_password2" name="password2" type="password" class="form-control">
To this:
<input placeholder="Password" name="new_password1" required id="id_new_password1" type="password" class="form-control">
<input placeholder="Confirm Password" name="new_password2" required id="id_new_password2"
type="password" class="form-control">
What is happening is that your name entries are wrong, which causes the form to fail validation in general in the default password reset view and get returned with a generic error.
Just swap those out and the form should work fine.
Related
I am having problem with setting up logic for if statement in HTML template with Jinja.
What should I input in place of ??? in the below code?
I don't want the user to be able to post empty field, therefore, I have decided to disable the submit button while the textarea is empty (e.g.: it has different css style with the form__submit__disabled class).
I have tried inputting in the ??? place content, entry, form__textarea, but it doesn't work.
<form class="form" action="/" method="POST">
<p class="form__input">
<textarea name="content" id="entry" class="form__textarea" aria-label="Entry contents" placeholder="Type here..."></textarea>
</p>
{% if ??? is none %}
<button type="submit" class="form__submit__disabled" disabled>Add entry</button>
{% else %}
<button type="submit" class="form__submit">Add entry</button>
{% endif %}
</form>
A better idea, for this requirement would be to use the required attribute of the textarea, and let the browser do the job of warning the end user that this field should be filled in before submitting.
<form class="form" action="/" method="POST">
<p class="form__input">
<textarea name="content"
id="entry"
class="form__textarea"
aria-label="Entry contents"
placeholder="Type here..."
required></textarea>
</p>
<button type="submit"
class="form__submit">
Add entry
</button>
</form>
So I'm getting a bunch of comment objects in a dictionary called commentQuery. However, the comments are not printing out on the actual post page.
Anyone see why? Thanks! (as you can see, I'm trying both the commentQueries and commentQuery options - neither are displaying on the page!)
views.py:
def comment(request):
username = request.POST.get("username")
itemID = request.POST.get("itemID")
comment = request.POST.get("comment")
new = Comment.objects.create(username = username, comment = comment, itemID = itemID)
new.save()
commentQuery = Comment.objects.all()
return render(request, "auctions/post.html", { "commentQuery": commentQueries})
post.html:
<form name="comment"
action="/comment"
method="post">
{% csrf_token %}
<h2>Comments</h2>
{% if user.is_authenticated %}
<input autofocus class="form-control" type="text" name="comment" placeholder="Enter Comment">
<input autofocus class="form-control" type="hidden" name="itemID" value={{p.title}}{{p.price}}>
<input autofocus class="form-control" type="hidden" name="username" value={{user.username}}>
<input class="btn btn-primary" type="submit" value="Add Comment">
{% endif %}
</form>
{% for commentQuery in commentQueries %}
<li>{{ commentQuery.comment }} by {{ commentQueries.username }}</li>
{% endfor %}
{% endblock %}
I changed the path to path("comment", views.comment, name="comment"),"
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.
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'):
I'm working on adding subscriptions using django-registration. Right now, I'm trying to create a Paypal form on the registration_complete page.
I have created a session variable as follows:
def user_created(sender, user, request, **kwargs):
form = RegistrationFormEx(data=request.POST)
new_user = User.objects.get(username=request.POST['username'])
digest=hmac.new(str(request.POST['username'])+str(request.POST['password1']), str(request.POST['password1']),hashlib.sha1).hexdigest()
new_profile = UserProfile(user=new_user,api_key=digest)
new_profile.save()
#now add other fields including password hash as well
uid = new_profile.id
#Add username to session to pass it via Paypal later
request.session['username']=request.POST['username']
merchant_profile = MerchantProfile(user_id=uid,
create_time=datetime.datetime.now(),
modified_time=datetime.datetime.now(),
payment_card_id=uid,
current_state=1,
name=request.POST['name'],
)
merchant_profile.save()
return new_user
user_registered.connect(user_created)
My template for the Paypal form is is as follows:
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<p>
{% trans "You are now registered. Activation email sent." %}
<form action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="sumit_1349250468_per#sample.com">
<input type="hidden" name="item_name" value="registration charge {{ request.session.username }}">
<input type="hidden" name="item_number" value="1">
<input type="hidden" name="amount" value="9.00">
<input type="hidden" name="no_shipping" value="0">
<input type="hidden" name="no_note" value="1">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="lc" value="AU">
<input type="hidden" name="bn" value="PP-BuyNowBF">
<input type="image" src="https://www.paypal.com/en_AU/i/btn/btn_buynow_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online.">
<img alt="" border="0" src="https://www.paypal.com/en_AU/i/scr/pixel.gif" width="1" height="1">
<input type="hidden" name="return" value="http://url/payment_result?response=success">
<input type="hidden" name="cancel_return" value="http://url/sorry">
</form>
</p>
{% endblock %}
Without changing any views, how can I print the value for request.session.username in this template?
In settings.py, TEMPLATE_CONTEXT_PROCESSORS should include django.core.context_processors.request - This makes the request variable available to your templates.
Although, a word of warning: When the user activates his email and signs in after returning, the session variable will probably have changed.