I've been trying to make django send a mail to one user once the user input his email but it keeps failing. For example, user A signup to my list and django sent him a mail. User B signup to my list and django sends both user A and B a mail.
I don't want that kind of process, I want to send a mail to each user once they fill in their email address. So that when another user signup django won't send the current user and the ones already on the database the same mail.
Below are my codes:
send invitation
Subject='Join Me'
message=loader.get_template('letter.txt')
from_email='test#testing.com'
def invite_me(request):
if request.method=="POST":
form=InviteForm(request.POST)
if form.is_valid():
form.save()
#get input data and send email to the user.
send_mail(Subject,message.render(Context()),from_email,Invite.objects.values_list('email_address', flat=True))
return HttpResponse('Thanks For Inputting Your Email, Go Check Your Inbox!')
else:
return HttpResponse('Invalid Email Address')
else:
form=InviteForm()
return render_to_response('home.html',{'InviteForm':InviteForm},context_instance=RequestContext(request))
You are using: Invite.objects.values_list('email_address', flat=True), which returns a List of all the email_address fields for all the Invites in your database.
This means that all the registered Invite's will receive an email.
I assume InviteForm is a ModelForm for you Invite object. ModelForm.save returns the newly created object, so you should be doing:
invite = form.save()
send_mail(Subject,message.render(Context()),from_email,[invite.email_address])
Remember that send_mail expects an iterable, so using a list here is required, this is achieved by using [invite.email_address] and not just invite.email_address.
Related
Hello I am new to django and web programming. I am building a website for my school that allows students to schedule online advising appointments.
I need to be able to email students temporary passcodes to their student emails and then validate them on the next page. I have an email form :
class EmailForm(forms.Form):
student_email = forms.EmailField(max_length = 200, label = 'Mail')
def clean_student_email(self):
student_email = self.cleaned_data['student_email']
if not student_email.endswith('.edu'):
raise ValidationError("Please enter your school email that ends with #edu")
return student_email
and a login view
def login(request):
if request.method == 'POST':
form = EmailForm(request.POST)
if form.is_valid():
student_email = form.cleaned_data['student_email']
random_code = get_random_string()
subject = "Temporary Advising Code"
message = f'Your temporary code is: \n code: {random_code}'
send_mail(subject, message, 'advising email', [student_email])
return HttpResponseRedirect('/enter_code/', {'form' : form})
else:
form = EmailForm()
return render(request, 'login/login.html', {'form' : form})
Now I am able to generate a random string and send it to the students email but I am wondering if someone can tell me how I can validate that string on the next page.
I would advice against your approach.
But I would suggest to check how password reset token generator works in django .
Source: PasswordResetTokenGenerator
You can make something very similar to generate a token which you will send to students.
You don't need to store such token as you can easily generate it again ( when it comes to verification ).
So the idea here is to generate the token using some data which after password is changed or set by students - the token will no longer be valid.
You can even incorporate a expiration time if needed.
And you don't need to generate temporary password either ( which is something i don't like very much ).
So instead of sending students the temp password and asking them to log in with that - you would just send them a link with the token and by accessing the page with that token - they will be able to set a password.
I want to use django's default password reset view "PasswordResetView" which let's the user reset his password when he forgets it in a template that already has a view that i built on my own, after looking at the tutorials and the questions i found how to use it only on a different template that is made only for the password reset, but i don't want the user to go to a different page just to change his password when he forgets it, i want to make it in a bootstrap modal in the home page.
here is my home view that i want to add PasswordResetView functionality to it:
def home(request):
user = request.user
signin_form = SigninForm()
signup_form = SignupForm()
if request.method == "POST":
if 'signin_form' in request.POST:
signin_form = SigninForm(request.POST)
if signin_form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
elif user is None:
messages.error(request, 'ُEmail or password is incorrect')
if 'signup_form' in request.POST:
signup_form = SignupForm(request.POST)
if signup_form.is_valid():
signup_form.save()
full_name = signup_form.cleaned_data.get('full_name')
email = signup_form.cleaned_data.get('email')
raw_password = signup_form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
login(request, account)
context = {'signin_form': signin_form,'signup_form': signup_form}
return render(request, 'main/home.html', context)
PS: i tried copy pasting the source code of that view (PasswordResetView) from django's source code in my view but i found some errors because it's a class based view, so if you find this the proper way, guide me to do it
or if i can't merge them somehow how to create a custom one
this is what i found in the other answers which lets you use it in a certain template that has only that view (PasswordResetView) which is not what i want:
from django.contrib.auth import views as auth_views
path('password_reset/', auth_views.PasswordResetView.as_view(template_name="myapp/mytemplate.html",form_class=mypasswordresetform),name="reset_password"),
I'll give you a simple approach to having a password reset feature on your django application. Before having any code, let me give a brief exlanation of the process. What you want to do is get a user to input their email, check if there is any user with that email, then if there is one, send an email to that address with a uniquely generated link.
From this link, you should be able to extract the user object which you need to change password. An example would be to use django's signing module. This link will simply need to redirect the user to a template where there is a form with 2 fields i.e. New Password and Verify Password.
Django's generic views come with this functionality out-of-the-box if you are using Django's authentication module, but you aren't forced to use it, but its best to do so.
Here I'll only show you how to collect the email address on the same view as you said you wanted.
def home(request):
# ...your other code
if request.method == 'post':
if 'reset_password' in request.POST:
email = request.POST.get("email", "")
user_qs = User.objects.filter(email=email)
if not user_qs.exists():
# send error message to user here
else:
user = user_qs.get()
# send email with uniquely generated url here.
The other aspects of generating a URL and sending the mail, I believe you can research these separately. But I hope you now have an idea of where and what to search.
I want to login with handler.
I have a code use session but i want to use handler:
I have visit :
https://docs.djangoproject.com/en/1.11/topics/auth/default/
But i don't understand complete.
I want to log user (with username or email and password)
Do you have a code for example or project in stackoverflow or github or . . . ???
login the user is easy if you are using default user model from django.contrib.auth.models
from django.contrib.auth import authenticate, login
def user_login(request):
# check here that request.method is POST or not.
user = authenticate(username=request.POST.get('username'), password=request.POST.get('password'))
if user is not None:
login(request, user)
# send some http response here that login successful or redirect to some other page
else:
# return an error page saying that username password not correct
authenticate function will check for username and password in User table in the database if it founds a user matching query then it returns the user object else it will return None. You might not want to manage sessions as django already sets a cookie for every user that successfully logs in so if user has logged in once then he will not be required to enter password again.
I am writing a web app using Django. I am trying to allow a user to see its profile and only his own.
if(not request.user.id == request.GET.get('user_id', '')):
raise PermissionDenied
My question is: is it safe to check this way or is it possible for a smart kid to somehow alter the value in request.user.id to match the user_id of anyone?
The user must be logged in before accessing this page using this:
user = LDAPBackend().authenticate(username=username, password=password)
if(user is not None):
login(request, user)
Yes it should be safe.
request.user get's only populated when authentication with session cookies. Unless and until someone steals the cookie or token it should be no issue.
One thing i don't understand is why do you need user_id parameter here to be explicitly passed.
if you are putting logged in compulsory to view the page. there are two way i can see this.
/profile
Directly get user profile corresponding to the request.user
/<username>
Query the profile corresponding to the username and compare it with request.user.id
request.user is set using AuthenticationMiddleware for each request:
Adds the user attribute, representing the currently-logged-in user, to every incoming HttpRequest object.
If a user is not logged in then request.user is set to Anonymous User. Have a look at Authentication in Web requests.
So, I am not sure how would a smart kid alter the id of the logged-in user.
Mostly, there is a one-to-one relation between the user and its profile. If that's the case you can modify the queryset to get the profile for request.user directly.
request.user is already an object about the current user who send the request to get the page. You can use login_required or to only allow user login to access (2 solutions : decorator or Mixin).
And then you can use your condition to load the page in the function. Example:
=> url.py:
url(r'^profile/$', login_required(app.views.profile), name='profile'),
=> views.py :
def profile(request):
try:
myProfile = User.objects.get(username=request.user.username)
except ObjectDoesNotExist:
return render(request, "error.html", {'message' : 'No Profile Found'})
return render(request, "app/profile.html",
{'myProfile': myProfile})
Like this you can only display YOUR profile (user who send the request) AND you need to be logged.
EDIT: if you don't want "try and catch" you can use get_object_or_404(User, username=request.user.username)
How can I mail a decrypted 'current password' to a django user just created.
eg I create a customer by inheriting the User model. Hence the user name and password get saved. Once the customer details are entered and saved. While overriding the save function for the customer form I trigger the send_mail function to send the mail to the admin_email specified on the form, and send the user name and password I entered on the form. It is observed that the password sent is hashed, of course for security. Is there a way in which I could decrypt it before sending it to the customer just created? I want to send it that way only.
Please guide
Sending raw password is a bad idea, it's not secure. If user forgets his password, reset password form should be used instead of finding raw password in mail inbox.
To answer your question I could suggest using form for getting raw password. If you'll have own form, you'll get access to all user-entered text, including password. Then you'll use that password to create new user and send email.