How to stop django to automatically active users while using UserRegisterForm - django

views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm, UserUpdateForm, ProfileUpdateForm
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class UserRegisterForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
using RegisterForm for Registration form django automatically
activate user.I want to add signup email confirmation before
activating user.

So it is pretty simple, you can give a commit=False while saving the form
if form.is_valid():
user=form.save(commit=False)
# sets the field to False
user.is_active=False
user.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Your account has been created! You are now able to log in')
return redirect('login')
you have also said that
I want to add signup email confirmation before activating user.
for this, you cancheck out these links from
2017: https://medium.com/#frfahim/django-registration-with-confirmation-email-bb5da011e4ef
or 2018:Django 2 - How to register a user using email confirmation and CBVs?

Related

How to Verify Email in Django using OTP and UserCreationForm

I am creating a Quiz App. In that I have a sign up page for user authentication which is using the default User Model and User CreationForm. I want to add a email verification in it by sending a otp on the email.
Please explain me how can I send otp on email using default user model and user creation form to verify the otp on the email.
My user app code is:
forms.py
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
email = forms.EmailField()
class Meta:
model = get_user_model()
fields = ['username', 'email', 'password1', 'password2']
views.py
import pyotp
from django.contrib.auth.models import User
from .forms import UserRegisterForm
from django.contrib import messages
from django.shortcuts import render, redirect
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
otp=pyotp.totp('base32secret3232')
form.save()
messages.success(request, f'Account Created for {User.username}. You can Login')
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
You can refer below article.
https://medium.com/analytics-vidhya/how-to-implement-otp-based-authentication-on-django-rest-framework-185ae8032f07#:~:text=Step%201%3A%20Find%20that%20phone,the%20authenticity%20of%20the%20user.

How to get individual users data after login in django?

iam new to django.Can anyone send me the code of signup and login page to get particular details of the username without using django.contrib.auth.models import User.
(i.e if we login with some usename then it should only give details of that username not remaining).
Find view you want manipulate user in, declare user like current_user = request.user. I will provide you my login and register views below. In examples shown below I had from django.contrib.auth.models import User, but you can modify it as shown above.
Register:
def registerPage(request):
if request.user.is_authenticated:
return redirect('todoapp:home')
else:
form = CreateUserForm()
if request.method == 'POST':
form = CreateUserForm(request.POST)
email = request.POST.get('email')
if form.is_valid():
if check_does_email_already_exist(email):
form.save()
messages.success(request, "User is registered sucessfully")
return redirect('todoapp:login')
else:
messages.warning(
request, "User with same email already exist")
else:
messages.warning(
request, "That username already exist or your password is too short")
context = {
'form': form,
}
return render(request, 'register.html', context)
Login:
def loginPage(request):
if request.user.is_authenticated:
return redirect('todoapp:home')
else:
if request.method == 'POST':
username = request.POST.get('uname')
password = request.POST.get('passwd')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
return redirect('todoapp:home')
else:
messages.warning(
request, "Your password or username isn't valid")
return redirect('todoapp:login')
else:
pass
return render(request, 'login.html')
These are my imports:
from django.shortcuts import render, redirect
from django.urls import reverse
from django.utils import timezone
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.shortcuts import get_object_or_404
from django.contrib.auth import authenticate, login, logout
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from .forms import CreateUserForm
And this is my forms.py:
from django.contrib.auth.forms import UserCreationForm
from django import forms
from django.contrib.auth.models import User
from django.forms import fields
class CreateUserForm(UserCreationForm):
class Meta:
model = User
fields = [
'username',
'email',
'password1',
'password2',
]
I hope my answer will help you.

I am having an error that says "ModelForm has no model class specified."

I was just watching a tutorial in youtube and i was just following what was indicated buti still got those errors.
Forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserRegisterForm(UserCreationForm):
email = forms.EmailField(max_length = 50)
class Meta:
model : User
fields = ['username', 'password1', 'password2']
views.py
from django.shortcuts import render, redirect
from django.contrib import messages
from .forms import UserRegisterForm
def register(request):
if request.method == 'POST':
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'Account created for {username}!')
return redirect('home')
else:
form = UserRegisterForm()
return render (request, 'users/register.html', {'form':form})

Django, on registering a user: AttributeError: 'AnonymousUser' object has no attribute '_meta'

On trying to register a new user using the wp_register (this is a different type of user), I get the following error:
AttributeError: 'AnonymousUser' object has no attribute '_meta'
There are various answers on this, but none solved my problem.
The system was working fine until I tried to add different views in for the different users (W and WP) I also added the field 'description' (as a test) to the registration form, and am also attempting to create two different profiles for two different users (WPs and Ws). I have created, as you will see below, a separate registration page for wps (user type2), referenced by profile_wp, register_WP etc as well, and on trying to register a user using this form, I receive the error referenced above.
The various relevant bits of my code are below
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile
class UserRegisterForm(UserCreationForm): #form that inherits from the usercreationform
email = forms.EmailField()
class Meta:
model = User
class Register_WP_Form(UserCreationForm): #form that inherits from the usercreationform
email = forms.EmailField()
description=forms.EmailField()
#choice = forms.ChoiceField(required=True, widget=forms.RadioSelect(
#attrs={'class': 'Radio'}), choices=(('option1','I am a W'),('option2','I am a WP'),))
class Meta:
model = User
#when this form validates it creates a new user
#type the fields to be shown on your form, in that order.
fields = ['username','email','password1','password2','description']
class UserUpdateForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username','email']
class ProfileUpdateForm(forms.ModelForm):
class Meta:
model= Profile
fields=['image']
views.py
#USERS (register) view.py
from django.shortcuts import render,redirect
from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages #this allows us flash messages for testing
from django.contrib.auth.decorators import login_required
from .forms import UserRegisterForm
from .forms import UserUpdateForm
from .forms import Register_WP_Form
from .forms import ProfileUpdateForm
from django.contrib.auth.decorators import login_required
# Create your views here.
def register(request):
if request.method =='POST':
#this UserRegisterForm is created in forms.py and inherits from UserCreationForm (the ready made form)
form = UserRegisterForm(request.POST) #create a form that has the data that was in request.POST
if form.is_valid(): #is the form valid (do you have a username like this already, passwords match?
form.save()#this just saves the account, hashes the password and it's all done for you!
username = form.cleaned_data.get('username')
messages.success(request,f'Account created for {username}, you can now login.')
return redirect('socialmedia-moreinfo')
else:
form =UserRegisterForm() #if the form input is invalid, render the empty form again
#above we are creating a blank form and rendering it to the template
return render(request, 'users/register.html',{'form':form})
#different types of messages message . debug, inf success warning and error
def register_wp(request):
if request.method =='POST':
#this UserRegisterForm is created in forms.py and inherits from UserCreationForm (the ready made form)
form = Register_WP_Form(request.POST) #create a form that has the data that was in request.POST
if form.is_valid(): #is the form valid (do you have a username like this already, passwords match?
form.save()#this just saves the account, hashes the password and it's all done for you!
username = form.cleaned_data.get('username')
messages.success(request,f'Account created for {username}, you can now login.')
print("SUCCESS")
return redirect('profile-wp')
else:
form =Register_WP_Form() #if the form input is invalid, render the empty form again
#above we are creating a blank form and rendering it to the template
return render(request, 'users/register-wp.html',{'form':form})
#different types of messages message . debug, inf success warning and error
def register_w(request):
if request.method =='POST':
#this UserRegisterForm is created in forms.py and inherits from UserCreationForm (the ready made form)
form = UserRegisterForm(request.POST) #create a form that has the data that was in request.POST
if form.is_valid(): #is the form valid (do you have a username like this already, passwords match?
form.save()#this just saves the account, hashes the password and it's all done for you!
username = form.cleaned_data.get('username')
messages.success(request,f'Account created for {username}, you can now login.')
return redirect('profile')
else:
form =UserRegisterForm() #if the form input is invalid, render the empty form again
#above we are creating a blank form and rendering it to the template
return render(request, 'users/register-w.html',{'form':form})
#different types of messages message . debug, inf success warning and error
#login_required #this is a decorator (adds functionality to an existing function)
def profile(request):
if request.method =='POST':
u_form =UserUpdateForm(request.POST,instance=request.user)
p_form =ProfileUpdateForm(request.POST, request.FILES,instance=request.user.profile)
if u_form.is_valid() and p_form.is_valid():
u_form.save()
p_form.save()
messages.success(request,f'Your account has been updated')
return redirect('profile')
else:
u_form =UserUpdateForm(instance=request.user)
p_form =ProfileUpdateForm(instance=request.user.profile)
context={
'u_form': u_form,
'p_form': p_form
}
return render(request,'users/profile.html',context)
#add a login required dectorator that django provides
#we want a user to be logged in to view this profile view
#see the very top to import decorators
def profile_wp(request):
if request.method =='POST':
u_form =UserUpdateForm(request.POST,instance=request.user)
p_form =ProfileUpdateForm(request.POST, request.FILES,instance=request.user.profile)
if u_form.is_valid() and p_form.is_valid():
u_form.save()
p_form.save()
messages.success(request,f'Your account has been updated')
return redirect('profile-wp')
else:
u_form =UserUpdateForm(instance=request.user)
p_form =ProfileUpdateForm(instance=request.user.profile)
context={
'u_form': u_form,
'p_form': p_form
}
return render(request,'users/profile-wp.html',context)
#add a login required dectorator that django provides
#we want a user to be logged in to view this profile view
#see the very top to import decorators
urls.py
#URLS in main project directory
from django.contrib import admin
from django.contrib.auth import views as auth_views #add this for user views
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
from users import views as user_views
#now create paths for the user views (default django user views) below
urlpatterns = [
path('admin/', admin.site.urls),
path('register/',user_views.register, name='register'),
path('register_wp/',user_views.register_wp, name='register_wp'),
path('register_w/',user_views.register_w, name='register_w'),
#path('socialmedia/',include('socialmedia.urls')),
path('login/',auth_views.LoginView.as_view(template_name='users/login.html'), name='login'),
path('logout/', auth_views.LogoutView.as_view(template_name='users/logout.html'), name='logout'),
path('profile/',user_views.profile, name='profile'),
path('profile-wp/',user_views.profile_wp, name='profile-wp'),
path('',include('socialmedia.urls')),
]
if settings.DEBUG:#if we currently in DEBUG mode, then add the below to URL patterns
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

How to automatically login a user after registration in django

This is what I am currently using for registration:
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
messages.info(request, "Thanks for registering. Please login to continue.")
return HttpResponseRedirect("/dashboard/")
else:
form = UserCreationForm()
return render_to_response("accounts/register.html", {
'form': form,
}, context_instance=RequestContext(request))
Is it possible not to require the user to login manually after creating an account, but rather simply to log them in automatically? Thanks.
edit: I had tried the login() function without success. I believe the problem is that AUTHENTICATION_BACKENDS was not set.
Using the authenticate() and login() functions:
from django.contrib.auth import authenticate, login
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
messages.info(request, "Thanks for registering. You are now logged in.")
new_user = authenticate(username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
)
login(request, new_user)
return HttpResponseRedirect("/dashboard/")
for class based views here was the code that worked for me (originally Django 1.7, updated for 2.1)
from django.contrib.auth import authenticate, login
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.views.generic import FormView
class SignUp(FormView):
template_name = 'signup.html'
form_class = UserCreateForm
success_url='/account'
def form_valid(self, form):
#save the new user first
form.save()
#get the username and password
username = self.request.POST['username']
password = self.request.POST['password1']
#authenticate user then login
user = authenticate(username=username, password=password)
login(self.request, user)
return HttpResponseRedirect(self.get_success_url)
The accepted answer doesn't seem to work with Django 4.0 (for me, at least), or alternatively it doesn't work with custom user models that have custom user managers.
This is how I solved the issue (adapted from https://stackoverflow.com/a/31491942 and https://stackoverflow.com/a/68515276):
from django.views.generic import CreateView
from django.urls import reverse_lazy
from django.contrib.auth import authenticate, login
from your.custom.user.models import User
class SignUpView(CreateView):
model = User
fields = ["username", "email", "password"]
success_url = reverse_lazy("success_url_name") # change this with your own URL
def form_valid(self, form):
# create the user object
user = form.save(commit=False)
# set password manually
# as otherwise the User will be saved with unhashed password
user.set_password(form.cleaned_data.get("password"))
# save your User object to the database
user.save()
# get email and password
email = form.cleaned_data.get("email")
password = form.cleaned_data.get("password")
# authenticate your user with unhashed password, because `authenticate` hashes it again
authenticated_user = authenticate(email=email, password=password)
# log in
login(self.request, authenticated_user)
return redirect(self.success_url)
You need to manually set the password, so that the database contains the hashed password. Without that, your unhashed password will be saved to the database, which will prevent you from logging in afterwards, as authentication involves hashing the password and checking that against the database.
using only "login()" in django-4.0.3
from django.contrib.auth import login
def registration(request):
if request.POST:
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
login(request, user)
username = form.cleaned_data.get('username')
messages.success(request, f'Account created for {username}')
return redirect('home')
You can subclass Django's UserCreationForm and override it's save method to log them in when commit=True.
forms.py
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
class CustomUserCreationForm(UserCreationForm):
"""
A ModelForm for creating a User and logging
them in after commiting a save of the form.
"""
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.request = request
class Meta(UserCreationForm.Meta):
pass
def save(self, commit=True):
user = super().save(commit=commit)
if commit:
auth_user = authenticate(
username=self.cleaned_data['username'],
password=self.cleaned_data['password1']
)
login(self.request, auth_user)
return user
You just need to make sure you pass in a request object when you instantiate the form. You can do that by overriding the view's get_form_kwargs method.
views.py
def get_form_kwargs(self):
form_kwargs = super().get_form_kwargs()
form_kwargs['request'] = self.request
return form_kwargs
Or, make sure when you instantiate a form_class you do CustomUserCreationForm(data=request.POST, request=self.request).
The Django auth.login function makes it easy to log in a user, given a request and User instance.
Note: remember to add the necessary imports for the following examples.
from django.contrib.auth import login
from django.shortcuts import render, redirect
In a function-based view, the following should work.
if form.is_valid():
user = form.save()
login(request, user)
return redirect("desired-url")
For a class-based view (such as CreateView or FormView), you can override the form_valid method:
def form_valid(self, form):
"""If the form is valid, save the associated model and log the user in."""
user = form.save()
login(self.request, user)
return redirect(self.success_url)