I was trying to create a new user with create_user but its not working - django-views

This is a registration page function
def register(request):
if request.method=="POST":
username= request.POST['username']
email= request.POST['email']
password= request.POST['password']
password2= request.POST['password2']
if password == password2:
if User.objects.filter(email=email).exists():
messages.info(request,'Email Already Used')
return redirect('register')
elif User.objects.filter(username=username).exists():
messages.info(request,'Username Already Used')
return redirect('register')
else:
user=User.objects.create_user(username=username,email=email,password=password2) #create_user not working
user.save()
return redirect('login')
else:
messages.info(request,'password not same')
return redirect('register')
else:
return render(request,'register.html')
this is the register.html file
<h1>SIGN UP HERE</h1>
<style>
h5 {
color: red
}
</style>
{% for message in massages %}
<h5>{{message}}</h5>
{% endfor %}
<form method="POST" action="register">
{% csrf_token %}
<p>Username(admission number):</p>
<input type="text" name="username" />
<P>Email</P>
<input type="email" name="email" />
<p>Password:</p>
<input type="password" name="password" />
<p>Repeat password</p>
<input type="password" name="password2" /><br>
<input type="submit" />
</form>
I have imported User model for create_user method
from django.contrib.auth.models import User
but its not working

I don't know why you would want to create a function-based view for User creation. A much simpler way to do this is to build a class-based view using django's User model:
from users.models import User
from .forms import RegisterForm
from django.views import generic
class UserRegistration(generic.CreateView):
form_class = RegisterForm
template_name = 'register.html'
success_url = reverse_lazy('home')
In your forms.py file (in whichever app you are creating the users) you add the RegisterForm:
from django.contrib.auth.models import User
from django import forms
from django.contrib.auth.forms import UserCreationForm
class RegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
username, password1, and password2 are already built in fields for django Users, so it's already done for you.
Then in your register.html file all you need is to add the from:
<h1>SIGN UP HERE</h1>
<style>
h5 {
color: red
}
</style>
{% for message in massages %}
<h5>{{message}}</h5>
{% endfor %}
<form method="POST" action="register">
{% csrf_token %}
{{form.as_p}}
</form>
{{form.as_p}} renders all the fields in the order they appear in in your RegisterForm.

Related

authenticate() is not validate data properly django

When I try to click on login button it always execute the invalid credentials instead of redirect to the index page.. What I did is that in database create table name signup and wants to validate all the data from that table.. Here signup_data function is works well but in login_data cannot authenticate the user.
Models.py
from django.db import models
class signup(models.Model):
username = models.CharField(max_length=10)
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
email = models.EmailField()
password = models.CharField(max_length=10)
Forms.py
from django.forms import ModelForm
from . models import signup
from django import forms
class signupform(ModelForm):
username= forms.CharField(max_length=10,widget=forms.TextInput(attrs={'class':'form-control'}))
first_name = forms.CharField(max_length=20, widget=forms.TextInput(attrs={'class': 'form-control'}))
last_name = forms.CharField(max_length=20,widget=forms.TextInput(attrs={'class': 'form-control'}))
email = forms.EmailField(max_length=20,widget=forms.EmailInput(attrs={'class': 'form-control'}))
password = forms.CharField(max_length=10,widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model = signup
fields = '__all__'
Views.py
from django.shortcuts import render,redirect
from . forms import signupform
from . models import signup
from django.contrib import messages
from django.contrib.auth import login,authenticate
def index(response):
return render(response,'login_module/index.html')
def signup_data(response):
if response.method == 'POST':
form = signupform(response.POST)
if form.is_valid():
username = form.cleaned_data['username']
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
if signup.objects.filter(username=username).exists():
# messages.add_message(response,messages.WARNING,'Username is already taken')
messages.error(response,'Username is already taken')
return redirect('signup')
elif signup.objects.filter(email=email).exists():
messages.error(response,'Email is already taken')
# messages.add_message(response,messages.WARNING,'Email is already taken')
return redirect('signup')
else:
register_instance = signup(username=username, first_name=first_name, last_name=last_name, email=email, password=password)
register_instance.save()
messages.success(response,'Registered Successfull')
return redirect('signup')
else:
form = signupform()
return render(response,'login_module/signup.html',{'form':form, 'message': messages})
def login_data(request):
form = signupform(request.POST or None)
if request.method == "POST":
username = request.POST['username']
password = request.POST['password']
user = authenticate(username=username, password=password)
if user is not None:
login(request,user)
return redirect('index')
else:
messages.error(request,'Invalid Credentials')
return redirect('login')
else:
return render(request,'login_module/login.html',{'form':form, 'message': messages})
Login.html
{% extends 'login_module/base.html' %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-12 text-center mt-50">
<h1>Login Page</h1>
</div>
</div>
<div class="row">
<div class="col-md-4 offset-md-4 ">
<form method="post" action="{% url 'login' %}">
{% csrf_token %}
<div class="form-group rounded-top">
{{ form.username.label_tag }} {{ form.username }}
</div>
<div class="form-group rounded-top">
{{ form.password.label_tag }} {{ form.password }}
</div>
<div class="text-center">
<button type="submit" class="btn btn-primary">Login</button>
</div>
</form>
</div>
</div>
<div class="text-center mt-50">
{% if messages %}
{% for message in messages %}
<div class="alert alert-danger" role="alert">
{{ message }}
{% endfor %}
{% endif %}
</div>
</div>
{% endblock %}
Login Page
As far as I can tell you are creating a signup object when signing up, but when trying to login with authenticate django is looking for the generic User model. You have to create a User in the database rather than a signup object to use authenticate.

Django form not saving email

My views-
from django.shortcuts import render, redirect
from .AuthForms import registerUserForm
from django.contrib import messages
from django.contrib.auth import login, authenticate
def registerUsers(request):
if request.method == 'POST':
ucf = registerUserForm(request.POST)
if ucf.is_valid():
ucf.save()
new_user = authenticate(username = ucf.cleaned_data['username'], password = ucf.cleaned_data['password1'])
login(request, new_user)
return redirect('content')
else:
ucf = registerUserForm()
return render(request, 'LoginAndSignUp/SignUpPage.html', {'ucf': ucf})
My form -
I have extended the usercreationform
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm, AuthenticationForm , PasswordResetForm
from django import forms
class registerUserForm(UserCreationForm):
email = forms.EmailField(widget = forms.EmailInput(attrs={'placeholder':'Email', 'autocomplete':'off'}))
username = forms.CharField(widget= forms.TextInput(attrs={'placeholder':'Username','autocomplete':'off',}))
password1 = forms.CharField(widget= forms.PasswordInput(attrs={'placeholder':'Password'}))
password2 = None
class meta:
model = User
fields = ['username', 'email', 'password1']
class userLoginForm(AuthenticationForm):
username = forms.CharField(widget= forms.TextInput(attrs={'placeholder':'Username','autocomplete':'off'}))
password = forms.CharField(widget= forms.PasswordInput(attrs={'placeholder':'Password'}))
class userPasswordResetEmailForm(PasswordResetForm):
email = forms.EmailField(widget = forms.EmailInput(attrs={'placeholder':'Enter your email', 'autocomplete':'off',}))
class Meta:
model = User
fields = '__all__'
Here is my template. I suppose everything is correct but still its not saving the email
<form novalidate action="" method="post">
{%csrf_token%}
<div class="fieldWrapper">
{{ucf.email.errors}}
{{ucf.email}}
</div>
<div class="fieldWrapper">
{{ucf.username.errors}}
{{ucf.username}}
</div>
<div class="fieldWrapper">
{{ucf.password1.errors}}
{{ucf.password1}}
</div>
<div style="margin-bottom: 4%;">
<span class="director">Already with us? Log In</span>
<div class="director">
<i class="fa fa-compass"></i> Explore anonymously
</div>
</div>
<button class="primaryButton" type="submit">Sign Up</button>
</form>
The email field is not saving the email to database wherease the username and password is correctly being saved. Someone please help
Your code seems to be fine. I recreated your project and it works as intended. username, password and email are saved to the auth_user table. This is what mine looks like:
urls.py
urlpatterns = [
// other urls
path('users/', register_users, name='create_user')
]
views.py
from django.shortcuts import render, redirect
from django.contrib.auth import login, authenticate
from users.forms import RegisterUserForm
def register_users(request):
if request.method == 'POST':
ucf = RegisterUserForm(request.POST)
if ucf.is_valid():
ucf.save()
new_user = authenticate(username=ucf.cleaned_data['username'], password=ucf.cleaned_data['password1'])
login(request, new_user)
return redirect('content')
else:
ucf = RegisterUserForm()
return render(request, 'users/sign_up_page.html', {'ucf': ucf})
forms.py
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from django import forms
class RegisterUserForm(UserCreationForm):
email = forms.EmailField(widget=forms.EmailInput(attrs={'placeholder': 'Email', 'autocomplete': 'off'}))
username = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'Username', 'autocomplete': 'off'}))
password1 = forms.CharField(widget=forms.PasswordInput(attrs={'placeholder': 'Password'}))
password2 = None
class Meta:
model = User
fields = ['username', 'email', 'password1']
sign_up_page.html
<form novalidate action="" method="post">
{% csrf_token %}
<div class="fieldWrapper">
{{ ucf.email.errors }}
{{ ucf.email }}
</div>
<div class="fieldWrapper">
{{ ucf.username.errors }}
{{ ucf.username }}
</div>
<div class="fieldWrapper">
{{ ucf.password1.errors }}
{{ ucf.password1 }}
</div>
<div style="margin-bottom: 4%;">
{# <span class="director">Already with us? Log In</span>#}
<div class="director">
{# <i class="fa fa-compass"></i> Explore anonymously#}
</div>
</div>
<button class="primaryButton" type="submit">Sign Up</button>
</form>

Uploading image through an upload form to Django User profile

I am trying to create a student register page that allows the student to upload a profile photo. I am using Django User model and a StudentProfile model that has a OneToOne relation with User. Here are my codes:
student\models.py:
from django.db import models
from django.contrib.auth.models import User
class StudentProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,)
avatar = models.ImageField(upload_to='student_profile/', null=True, blank=True)
def __str__(self):
return self.user.username
students/form.py:
from django import forms
class ImageUploadForm(forms.Form):
profile_photo = forms.ImageField()
eLearning/views.py:
from django.contrib.auth import authenticate, login, get_user_model
from django.http import HttpResponse
from django.shortcuts import render, redirect
from .forms import LoginForm, RegisterForm
from students.forms import ImageUploadForm
from students.models import StudentProfile
User = get_user_model()
def register_page(request):
register_form = RegisterForm(request.POST or None)
photo_upload_form = ImageUploadForm(request.POST, request.FILES)
context = {
"register_form": register_form,
"photo_upload form": photo_upload_form
}
if register_form.is_valid():
# print(register_form.cleaned_data)
username = register_form.cleaned_data.get("username")
first_name = register_form.cleaned_data.get("first_name")
last_name = register_form.cleaned_data.get("last_name")
email = register_form.cleaned_data.get("email")
password = register_form.cleaned_data.get("password")
new_user = User.objects.create_user(
username, email, password,
first_name=first_name,
last_name=last_name,
)
if photo_upload_form.is_valid():
user = username
avatar = photo_upload_form.cleaned_data.get("profile_photo")
new_user_profile = StudentProfile.objects.create(user, avatar)
print(new_user)
return render(request, "auth/register.html", context)
auth/register.html:
{% extends "base.html" %}
{% load static %}
{% block content %}
{% load crispy_forms_tags %}
<div class="container">
<div class="row my-4">
<div class="col-5">
<form action="" method="post" class="form-control">
{% csrf_token %}
{{ register_form|crispy }}
<input type="submit" class="btn btn-default" value="Submit">
</form>
</div>
<div class="col-5">
<form method="post" enctype="multipart/form-data" class="form-control">
{% csrf_token %}
<input id="id_image" type="file" class="my-2" name="image">
{{ photo_upload_form|crispy }}
</form>
</div>
</div>
</div>
{% endblock %}
I am facing 2 problems:
1) The ImageUploadForm is not rendering on to register.html
2) A StudentProfile is not being created. User is being created fine.
I also tried replacing form with ModelForm for ImageUploadForm but I get a NULL constraint for student_user since Django doesn't what user for StudentProfile is.
I have been looking through Stack Overflow. All solutions are about how to upload a user image to Django admin but I haven't found anything that shows how to associate the uploaded image to User model during registration. Forgive me if this is a repeated question. Thanks.
In your eLearning/views.py:
the context you are passing to the html page the _ is missing
context = {
"register_form": register_form,
"photo_upload form": photo_upload_form
}
This will be the reason for the ImageUploadForm is not rendering on to register.html
It's should be like
context = {
"register_form": register_form,
"photo_upload_form": photo_upload_form
}
So I figured it out. The real issue was with the register.html code. The submit button only worked for the register_form so the photo upload form was not validating, hence student profile entry was not being created. Here's the updated code:
eLearning/views.py:
from students.forms import ImageUploadForm
from students.views import upload_pic
def register_page(request):
register_form = RegisterForm(request.POST or None)
photo_upload_form = ImageUploadForm(request.POST, request.FILES)
context = {
"register_form": register_form,
"photo_upload_form": photo_upload_form
}
if register_form.is_valid():
username = register_form.cleaned_data.get("username")
first_name = register_form.cleaned_data.get("first_name")
last_name = register_form.cleaned_data.get("last_name")
email = register_form.cleaned_data.get("email")
password = register_form.cleaned_data.get("password")
new_user = User.objects.create_user(
username, email, password,
first_name=first_name,
last_name=last_name,
)
upload_pic(request, photo_upload_form, username=username)
return render(request, "auth/register.html", context)
students/views.py:
from django.contrib.auth import get_user_model
from django.http import HttpResponseRedirect
from django.shortcuts import render, redirect, HttpResponse
from .models import StudentProfile
from .forms import ImageUploadForm
def upload_pic(request, form, username):
if request.method == 'POST':
if form.is_valid():
User = get_user_model()
user = User.objects.get(username=username)
avatar = form.cleaned_data.get('profile_photo')
new_user_profile = StudentProfile.objects.create(user=user, avatar=avatar)
new_user_profile.save()
register.html:
{% extends "base.html" %}
{% load static %}
{% block content %}
{% load crispy_forms_tags %}
<div class="container">
<div class="row my-4">
<div class="col-5">
<form action="" method="post" enctype="multipart/form-data" class="form-control">
{% csrf_token %}
{{ register_form|crispy }}
{{ photo_upload_form|crispy }}
<input type="submit" class="btn btn-default" value="Submit">
</form>
</div>
</div>
</div>
{% endblock %}
You have to make sure enctype="multipart/form-data" is inside your tags or the image upload form will not get validated. I would also recommend adding an image validation method to your form.py. Something Sachin pointed out earlier: image form and validation. Hope this helps.

django registration auth - how to check valid input?

Could you review my code for improvement? Essentially, it works but it isn't user friendly. For example,(1) If the user puts in an invalid field, it doesn't tell them what field is invalid. (2) If a user tries to register (sign up) with an existing username, there is no way the user can distinguishes that error, specifically. Or if a user mis-type password confirm, the user won't know that mistake either. (3) Also, if the user produces an input error(s), the sign up page blanks out all the field and so the user has to re-enter in all the info. As you can imagine, that could be very frustrating for that user.
I tried to see if form.error_messages might help the user, the error_messages is useless.
How would you improve the code so that (1), (2), (3) is not a nuisance for the user? And one more thing, just curious about how you would change the css? I noticed that most professional website sign-up page highlight the input box that was invalid. I am clueless on how to apply changes to css for {{form|as_bootstrap}}
Many thanks for your help!
form.py:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class MyRegistrationForm(UserCreationForm):
email = forms.EmailField(required=True,help_text="Email field is required.")
firstname = forms.CharField(max_length=50, required=False, help_text="Optional. Can fill in later.")
lastname = forms.CharField(max_length=50, required=False, help_text="Optional. Can fill in later.")
class Meta:
model = User
fields = (
'username',
'email',
'password1',
'password2',
'firstname',
'lastname'
)
def save(self, commit=True):
user = super(UserCreationForm, self).save(commit=False)
user.email = self.cleaned_data["email"]
user.firstname = self.cleaned_data["firstname"]
user.lastname = self.cleaned_data["lastname"]
if commit:
user.save()
return user
views.py
from django.shortcuts import render, render_to_response
from django.http import HttpResponseRedirect
from django.contrib import auth
from django.core.context_processors import csrf
from forms import MyRegistrationForm
def register_user(request):
if request.method == 'POST':
form = MyRegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/account/register_success')
else:
form = MyRegistrationForm()
args = {}
args.update(csrf(request))
args['form']= form
print form.errors #this line doesn't print anything
return render_to_response('register.html', args)
else:
return HttpResponseRedirect('/')
def register_success(request):
return render_to_response('register_success.html')
register.html
{% extends 'base.html' %}
{% load bootstrap_toolkit %}
{
{% block title %}
<title>Register</title>
{% endblock %}
<body>
{% block content %}
<div class="col-sm-9 col-sm-offset-3 col-md-6 col-md-offset-2 main">
<h2>Register</h2>
{% if form.error_messages %}
<p class="error"> {{ form.error_messages }}.</p>
{% endif %}
<form class="form-signup" role="form" action="/account/register/" method="post"> {% csrf_token %}
{{ form|as_bootstrap }}
<input type="submit" value="Register" class="btn btn-primary"/>
</form>
</div>
{% endblock %}
</body>

Editing users in Django

I was trying to to edit a user using the form that i used to create the user,
I have no idea why i'm getting an error A user with that username already exists.
Here is my view:
def registration_edit(request):
""" Registration Step2:
The user should be authenticated to reach this step.
Authentication is provided by first step or user login.
"""
if request.user.is_authenticated():
if request.POST:
form = RegistrationForm(request.POST or None, instance=request.user)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('reg_step_2'))
else:
form = RegistrationForm(instance=request.user)
page = 'account'
title = 'Editing User Registration'
context = {'title': title, 'form': form, 'page': page}
template = 'customer/registration.djhtml'
return render_to_response(template, context, context_instance=RequestContext(request))
else:
messages.info(request, '<strong>Note</strong>: You must logged in to edit your account.')
return HttpResponseRedirect('/')
forms.py I did this form because I want to include firstname and lastname field be included on the registration.
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class RegistrationForm(UserCreationForm):
class Meta:
model = User
exclude = ('is_staff', 'is_active', 'is_superuser', 'last_login', 'date_joined', 'groups', 'user_permissions', 'password')
and here is my template
<form class="form-horizontal" action='.' method="POST">
{% csrf_token %}
<fieldset>
<div id="legend">
<legend class="">
{{ title|title }}
</legend>
</div>
{% for f in form %}
<div class="control-group">
<label class="control-label" for="username">{{ f.label }}</label>
<div class="controls">
{{ f }} <i style="color: orange">{{ f.errors|striptags }}</i>
</div>
</div>
{% endfor %}
<div class="controls">
<button class="btn btn-success">
Continue
</button>
</div>
</fieldset>
</form>
Anyone tell me where i was messing around here?
Any help would be much appreciated.
Your from inherits from UserCreationForm which cleans the username field.
In this case see UserChangeForm instead.