How to sent password reset mail from another view? - django

I have a view to create a restaurant.
In the same view a user is also being created.
After the user creation, I have to sent a mail to the user with the link to reset the password.
My view looks like:
def create_restaurant(request):
form = RestaurantForm()
user_form = RestaurantUserForm()
if request.method == 'POST':
form = RestaurantForm(request.POST, request.FILES)
user_form = RestaurantUserForm(request.POST)
if form.is_valid() and user_form.is_valid():
#----user is saved here------
user_obj = user_form.save()
#----have to sent the mail here------
#-----restaurant is saved here-----
restaurant_obj = form.save()
restaurant_obj.user = User.objects.get(id=user_obj.id)
restaurant_obj.save()
messages.success(request, 'Restaurant Added Successfully.')
return redirect('create_restaurant')
context = {
"title": "Add restaurant",
"form": form,
"user_form": user_form
}
return render(request, "restaurant/restaurant.html", context)
I have implemented the password reset procedure using
urlpatterns = [
path('reset_password/',
auth_views.PasswordResetView.as_view(template_name="password_reset.html"),
name='password_reset'
),
path('reset_password_sent/',
auth_views.PasswordResetDoneView.as_view(template_name="password_reset_sent.html"),
name='password_reset_done'
),
path('reset/<uidb64>/<token>/',
auth_views.PasswordResetConfirmView.as_view(template_name="password_reset_form.html"),
name='password_reset_confirm'
),
path('reset_password_complete/',
auth_views.PasswordResetCompleteView.as_view(template_name="password_reset_done.html"),
name='password_reset_complete'
)]
How can I sent the email as mentioned above?

You can add a function to handle email sending like this
if request.method == 'POST':
form = RestaurantForm(request.POST, request.FILES)
user_form = RestaurantUserForm(request.POST)
if form.is_valid() and user_form.is_valid():
#----user is saved here------
user_obj = user_form.save()
#----have to sent the mail here------
ctx = {add all your data which you want to add in your email template}
send_user_email(ctx)
#-----restaurant is saved here-----
restaurant_obj = form.save()
restaurant_obj.user = User.objects.get(id=user_obj.id)
restaurant_obj.save()
messages.success(request, 'Restaurant Added Successfully.')
return redirect('create_restaurant')
and this is your function which is responsible to send emails
def send_user_email(ctx):
mail_subject = ctx['subject']
message = get_template('email_temp/user_notification.html').render(ctx)
to_email = ctx['user']
email = EmailMessage(
mail_subject,
message,
DEFAULT_FROM_EMAIL,
to=[to_email]
)
email.content_subtype = "html"
email.send(fail_silently=False)
return JsonResponse({'success':'success'})
you need to import some required things
from django.template.loader import get_template
from django.core.mail import EmailMessage

Related

How I can return the email again to the form if the login is invalid

How I can return the register information again to the register Form if the email not valid because as default if the email invalid the form are resitting
def register_view(request, *args, **kwargs):
user = request.user
if user.is_authenticated:
return HttpResponse("You are already authenticated as " + str(user.email))
context = {}
if request.POST:
form = RegistrationForm(request.POST)
if form.is_valid():
form.save()
email = form.cleaned_data.get('email').lower()
raw_password = form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
login(request, account)
destination = kwargs.get("next")
if destination:
return redirect(destination)
return redirect('home')
else:
context['registration_form'] = form
else:
form = RegistrationForm()
context['registration_form'] = form
return render(request, 'account/my login/register.html', context)
if the form is invalid send the form back with the data in your request.
For example in your form validation else statement should be something like this:
return render(request, 'account/my login/register.html',{'form':form})
If you want to send only the email field back then clean the other fields in the form except for the email and send only the email data back.
if form.is_valid():
# form validation logic here
else:
return render(request, 'account/my login/register.html',{'form':form})

Error creating a multi-step form using Django session

I'm currently working on building a multi-step registration form in Django. I followed the official documentation which can be seen here. Although the forms do not show any error, the user does not get created. Is there a problem I might be overlooking?
def signup_step_one(request):
if request.user.is_authenticated:
return HttpResponseRedirect(reverse('accounts:personal-signup'))
else:
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
# collect form data in step 1
email = form.cleaned_data['email']
password = form.cleaned_data['password1']
# create a session and assign form data variables
request.session['email'] = email
request.session['password'] = password
return render(request, 'personal-signup-step-2.html', context={
'form': form,
"title": _('Create your personal account | Step 1 of 2'),
})
else:
form = CustomUserCreationForm()
return render(request, 'personal-signup-step-1.html', {
"title": _('Create your personal account | Step 1 of 2'),
'form': form,
})
def signup_step_two(request):
# create variables to hold session keys
email = request.session['email']
password = request.session['password']
if request.method == 'POST':
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.email = email
user.set_password(password)
user.first_name(form.cleaned_data['first_name'])
user.last_name(form.cleaned_data['last_name'])
user.save()
print('user created')
return HttpResponse('New user created')
else:
form = CustomUserCreationForm()
return render(request, 'personal-signup-step-2.html', {
"title": _('Create your account | Step 2 of 2'),
'form': form,
})
I noticed that the following line in signup_step_two function will always return the message "New user created" even if form is not valid:
return HttpResponse('New user created')
Put the above line inside the if statement. Also print form.errors in else statement or inside the template to check the problem.
Ex:
if form.is_valid():
# create the user
return HttpResponse('New user created')
else:
print(form.errors)

How do I Send mail on Updating user active in Django admin?

I have changed the registration process a bit as shown below. When from the admin panel when superuser checks active, the registered user() should get mail on pressing save button. How can I do that?
Views.py
def register(request):
if request.method == "POST":
form = RegistrationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
messages.success(request, "User saved")
return redirect("accounts:login")
else:
messages.error(request, "Error in form")
else:
form = RegistrationForm()
context = {"form": form}
return render(request, 'accounts/reg_form.html', context)
I achieved it through this link: Send an email if to a Django User if their active status is changed

How to test a new user activation in Django?

I am trying to test django.contrib.auth-based user signup view with django-nose, where an activation link is being sent to a new user:
def signup(request):
if request.method == 'POST':
user_form = SignUpForm(request.POST)
profile_form = ProfileForm(request.POST)
if user_form.is_valid() and profile_form.is_valid():
user = user_form.save(commit=False)
user.is_active = False
user.save()
user.profile.user_type = profile_form['user_type'].data
user.save()
current_site = get_current_site(request)
subject = 'activation email'
message = render_to_string('registration/account_activation_email.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
'token': account_activation_token.make_token(user),
})
user.email_user(subject, message)
return redirect('account_activation_sent')
else:
user_form = SignUpForm()
profile_form = ProfileForm()
return render(request, 'registration/signup.html', {
'user_form': user_form,
'profile_form': profile_form
})
Currently I use Django built-in email back-end, so that activation email is being sent to the server terminal.
I want to test the activation view which requires uid and token. Is there any way to access the email sent to the user? Is there any other way to test that?
Regenerating token in the test does not work, because hash value is generated using timestamp.

Django Creating custom URL for user profile

I have an app which allows users to create a profile and log in.
When a user login , he is redirected to 127.0.0.1:8000/profile/
The problem is , I want to customize the URL by adding the user's username to the end of URL e.g example 127.0.0.1:8000/profile/michael
This is a similar question to mine
Django - after login, redirect user to his custom page --> mysite.com/username
"get the username and then do a HttpResponseRedirect to the custom URL."
I just can't seem to figure out how could I pass a username as an argument for HttpResponseRedirect to process into a the custom URL properly.
return HttpResponseRedirect('/profile/?username=%s' % (username, request.path))
def Profile(request):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('world:LoginRequest'))
person = Person.objects.get(user=request.user)
return render(request,'profile.html',{'person':person})
my URL
url(
r'^profile/$',
'pet.views.Profile',
name = 'Profile'
),
NEW
my views.py
def LoginRequest(request):
if request.user.is_authenticated():
username = User.objects.get(username=request.user)
url = reverse('Profile', kwargs = {'username': username.username})
return HttpResponseRedirect(url)
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
Person = authenticate(username=username, password=password)
if Person is not None:
login(request, Person)
username= User.objects.get(username=request.user)
url = reverse('Profile', kwargs = {'username': username.username})
return HttpResponseRedirect(url)
return render(request, 'login.html',{'form': LoginForm()})
url(
r'^login/$',
'pet.views.LoginRequest',
name = 'LoginRequest'
),
url(
r'^profile/(?P<username>\w+)/$',
'pet.views.Profile',
name = 'Profile'
),
def Profile(request,username):
if not request.user.is_authenticated():
return HttpResponseRedirect(reverse('world:LoginRequest'))
board = Board.objects.filter(user=request.user)
person = Person.objects.get(user__username=username)
return render(request,'profile.html',{'board':board ,'person':person})
This would be the proper regex for your redirect URL, ie. don't modify the one you have.
url(r'^profile/(?P<username>\w+)/$', 'pet.views.myprofileview', name="detail_profile")
And then to pass an argument to the redirect:
url = reverse('detail_profile', kwargs={'username': profile.firstname})
return HttpResponseRedirect(url)
This leads to also having to define a new view:
def myprofileview(request, username):
person = Person.objects.get(user = request.user)
return render(request,'profile.html',{'person':person})
This would eliminate two behaviours in one view, which I find to be very nice!
We do it this way because it's a string that HttpResponseRedirect accepts so we have to build it accordingly.
This will make a redirect to the myprofileview view and "style", if you could call it that, your url /profile/michael/.
def LoginRequest(request):
if request.user.is_authenticated():
return HttpResponseRedirect(reverse('world:Profile',
kwargs={'username': request.user.username}))
if request.method == "POST":
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
Person = authenticate(username=username, password=password)
if Person is not None:
login(request, Person)
return HttpResponseRedirect(reverse('world:Profile',
kwargs={'username': username}))
return render(request, 'login.html',{'form': LoginForm()})