I set up sendgrid as following and it works perfectly when I use send_mail to send a test message
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.sendgrid.net'
EMAIL_HOST_USER = 'apikey'
EMAIL_HOST_PASSWORD = '******'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
Howerver when I implement it with an activation code in views.py for registration as bellow:
def register(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save() #completed sign up
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=password)
login(request, user)
# Create data in profile table for user
current_user = request.user
data=UserProfile()
data.user_id=current_user.id
data.image="images/users/user.png"
data.save()
current_site = get_current_site(request)
subject = 'Please Activate Your Account'
# load a template like get_template()
# and calls its render() method immediately.
message = render_to_string('user/activation_request.html', {
'user': user,
'domain': current_site.domain,
'uid': urlsafe_base64_encode(force_bytes(user.pk)),
# method will generate a hash value with user related data
'token': account_activation_token.make_token(user),
})
user.email_user(subject, message)
return redirect('activation_sent')
# messages.success(request, 'Your account has been created!')
# return HttpResponseRedirect('/')
else:
messages.warning(request,form.errors)
return HttpResponseRedirect('/register')
form = SignUpForm()
#category = Category.objects.all()
context = {
'form': form,
}
return render(request, 'user/register.html', context)
It throws out this error:
SMTPDataError at /register
(550, b'The from address does not match a verified Sender Identity. Mail cannot be sent until this error is resolved. Visit https://sendgrid.com/docs/for-developers/sending-email/sender-identity/ to see the Sender Identity requirements')
I have verified the sender and that's why It works with send_mail but it doesn't work with activation code.
Please someone have a look for me.
Thanks
It is missing sender email in following code:
user.email_user(subject, message)
It should be:
user.email_user(subject, message,"email#example.com")
Sendgrid requires to setup sender before you're able to send email.
Go to your sendgrid management page (https://app.sendgrid.com/settings/sender_auth) and create a sender. A sender must be verified.
Then django, you can set default email in settings.py
DEFAULT_FROM_EMAIL = <your sendgrid sender>
Related
I am trying to send user an email containing invitation/confirmation link.Command propmt is showing that email is being sent but user is not receiving any email.I am using my gmail account and also allows access by less secure apps on my account? What can be the possible errors?
Here is my settings file:-
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'someone#gmail.com'
EMAIL_HOST_PASSWORD = 'password'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER
while my view uilizing it is as follows:-
#csrf_protect
def signup(request):
if request.method == 'POST':
form = SignupForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_active = False
user.save()
current_site = get_current_site(request)
mail_subject = 'Activate your blog account.'
message = render_to_string('acc_active_email.html', {
'user': user,
'domain': current_site.domain,
'uid':urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token':account_activation_token.make_token(user),
})
to_email = form.cleaned_data.get('email')
email = EmailMessage(
mail_subject, message, to=[to_email]
)
email.send()
return JsonResponse({'success':True})
else:
form=SignupForm()
return JsonResponse({'errors': [(k, v[0]) for k, v in form.errors.items()]})
Strange enough that my console is showing the email but the targeted user did not receive that email.
The culprit is this line of your configuration:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
From django documentation on
console.EmailBackend:
Instead of sending out real emails the console backend just writes the
emails that would be sent to the standard output.
If you want to send out real emails choose a suitable backend. Since you seem to be attempting to use smtp you most likely want to use django's smtp.EmailBackend like this:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
I thank you in advance for any help you could give to me about this question.
I would like the user to be redirect automatically to another page in my Django web application in the case he click on the button in order to coming back to the last page, or when he came back to the login page again I would like to disconnect it and when he still logged and he try to access to the register page, I would to disconnect it or redirect to another page from my website.
I have already tried LoginMixin and redirect but nothing.
when I am already logged and backing to the previous page I mean the login page I am still logged and I am have the login page even when I am already logged, the same I can go back to the register page but I am already logged.
I am using Django 2.1.7 the latest version.
So help any help will be appreciated.
Thank you again.
Here is my code the correct one. maybe he can help anyone else.
def login(request):
if request.user.is_authenticated:
return redirect('index')
else:
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
def get_next_url():
#request = self.request
next_ = request.GET.get('next')
next_post = request.POST.get('next')
redirect_path = next_ or next_post or None
if is_safe_url(redirect_path, request.get_host()):
return redirect_path
return 'user-home'
# def get_client_ip(request):
# x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
# if x_forwarded_for:
# ip = x_forwarded_for.split(',')[0]
# else:
# ip = request.META.get('REMOTE_ADDR')
# return ip
def get_ip_address_from_request(request):
""" Makes the best attempt to get the client's real IP or return the loopback """
PRIVATE_IPS_PREFIX = ('10.', '172.', '192.', '127.')
ip_address = ''
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '')
if x_forwarded_for and ',' not in x_forwarded_for:
if not x_forwarded_for.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(x_forwarded_for):
ip_address = x_forwarded_for.strip()
else:
ips = [ip.strip() for ip in x_forwarded_for.split(',')]
for ip in ips:
if ip.startswith(PRIVATE_IPS_PREFIX):
continue
elif not is_valid_ip(ip):
continue
else:
ip_address = ip
break
if not ip_address:
x_real_ip = request.META.get('HTTP_X_REAL_IP', '')
if x_real_ip:
if not x_real_ip.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(x_real_ip):
ip_address = x_real_ip.strip()
if not ip_address:
remote_addr = request.META.get('REMOTE_ADDR', '')
if remote_addr:
if not remote_addr.startswith(PRIVATE_IPS_PREFIX) and is_valid_ip(remote_addr):
ip_address = remote_addr.strip()
if not ip_address:
ip = request.META.get('REMOTE_ADDR')
ip_address = ip
return ip_address
try:
ip = get_ip_address_from_request(request)
user = User.objects.get(email=email)
if user.check_password(password) and user.is_active:
email = user.email
user = auth.authenticate(email=email, password=password)
auth.login(request, user)
alert_connection = User.objects.filter(connection_info=True)
if alert_connection:
base_url = getattr(settings, 'BASE_URL', 'http://www.dram-access.com')
context = {
'base_url': base_url,
'ip': ip,
'email': request.user.email,
'first_name': request.user.first_name,
'last_name': request.user.last_name
}
txt_ = get_template("accounts/emails/send_just_logged.txt").render(context)
html_ = get_template("accounts/emails/send_just_logged.html").render(context)
subject = 'New connection on your DreamAccess account'
from_email = settings.DEFAULT_FROM_EMAIL
recipient_list = [request.user.email]
send_mail(
subject,
message=txt_,
from_email=from_email,
recipient_list=recipient_list,
html_message = html_,
fail_silently=False,
)
messages.success(request, 'You are now logged in on DreamAccess')
next_path = get_next_url()
return redirect(next_path)
elif user.check_password(password):
qs = User.objects.filter(email=email)
if qs.exists():
#user email registered check active
not_active = qs.filter(is_active=False).exists()
confirm_email = EmailActivation.objects.filter(email=email, activated=False, forced_expired=False)
#is_confirmable = confirm_email.confirmable().exists()
if confirm_email and not_active:
return redirect('account-user-inactive')
elif not_active:
return redirect("send-reactivation-message")
else:
messages.error(request, "Your password is invalid")
return redirect('login')
except User.DoesNotExist:
messages.error(request, "This username and password doesn't exist on DreamAccess")
return redirect('login')
else:
return render(request, 'accounts/login.html')`
My Register page code:
def register(request):
if request.user.is_authenticated:
return redirect('index')
else:
form = RegisterForm(request.POST, request.FILES or None)
context = {
'form': form
}
if form.is_valid():
#form.save()
first_name = form.cleaned_data.get('first_name')
last_name = form.cleaned_data.get('last_name')
username = form.cleaned_data.get('username')
email = form.cleaned_data.get('email')
country = form.cleaned_data.get('country')
types = form.cleaned_data.get('types')
password = form.cleaned_data.get('password')
password2 = form.cleaned_data.get('password2')
phone = form.cleaned_data.get('phone')
profile_pic = form.cleaned_data.get('profile_pic')
new_user = User.objects.create_user(first_name, last_name, username, email, country, types, password, phone, profile_pic)
else:
return render(request, 'accounts/register.html', context)
Please provide your code, if you have any. On the signup page view, your code should look like this:
if request.user.is_authenticated:
# HttpResponseRedirect('/redirectToNonRegisterPageURL/')
...
else:
# Load Sign Up Form
...
So I'm making an email verification system but urlsafe_base64_decode is returning None instead of the pk.
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
username = form.cleaned_data['username']
password = form.cleaned_data['password']
subject = 'Activá tu mail'
current_site = get_current_site(request)
encoded_uid = urlsafe_base64_encode(force_bytes(user.pk)).decode()
message = render_to_string('firstpage/acc_active_email.html', {
'user': user,
'domain': current_site.domain,
'uid': encoded_uid,
'token': account_activation_token.make_token(user),
})
to_email = form.cleaned_data['email']
from_email = 'backend_email#gmail.com'
send_mail(subject, message, from_email, [to_email])
user.set_password(password)
user.save()
user_profile=UserProfile.objects.create(user=user)
#returns user objects if credentials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('/')
return render(request, self.template_name, {'form': form})
Then the users clicks on a link and this is redirected to this function
def activate(request, uidb64=None, token=None):
uid = urlsafe_base64_decode(uidb64).decode()
user = User.objects.get(pk=uid)
if user is not None and account_activation_token.check_token(user, token):
user.is_active = True
user.save()
login(request, user)
# return redirect('home')
return HttpResponse('Thank you for your email confirmation. Now you can login your account.')
else:
print(user)
print(uid)
print(account_activation_token.check_token(user, token))
return HttpResponse('Activation link is invalid!')
uidb64 returns the same as urlsafe_base64_encode(force_bytes(user.pk)).decode() but urlsafe_base64_decode(uidb64).decode() returns None.
I'm using Django 2.1 by the way.
You need to use force_text to return a str object representing arbitrary object and keep the lazy objects, use this - force_text(urlsafe_base64_decode(uidb64))
For more reference you can visit the documentation
-https://docs.djangoproject.com/en/2.1/ref/utils/#django.utils.encoding.force_text
Hope this will help you.
This is very late. But for anyone like me that stumbles upon this and has the exact same problem.
Django 3 >>
The problem is on this line
'token': account_activation_token.make_token(user),
And the reason is because the user given here is a form instead of a proper user instance.
Therefore, for solution:
user_instance = request.user # if the user is logged in or
user_instance = get_user_model() # if you're using default user model or
user_instance = YourUserModel # if you are using a custom user model
Then:
'token': account_activation_token.make_token(user_instance),
My form sends the email from the account listed in my settings.py fine, but in the message I only get the subject part of the form and the message part. There is no sender part within the email, so I can't tell who would be sending the email. Does anyone know how to fix this?
My forms.py
class ContactForm(forms.Form):
subject = forms.CharField(max_length=50)
message = forms.CharField()
sender = forms.EmailField()
My Views.py contact function
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
sender = form.cleaned_data['sender']
recipients = ['otheremail#gmail.com']
send_mail(subject, message, sender, recipients)
return HttpResponseRedirect('/thanks/')
else:
form = ContactForm()
return render(request, "contact.html", {'form':form,})
My Settings.py
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'myemail#gmail.com'
EMAIL_HOST_PASSWORD = 'mypassword'
That code should work fine. I have implemented the same thing below and it works, but I had one issue with gmail that you might be having.
send_mail(Subject, Message, 'myemail#example.ca', To)
The issue was that in order to have the sender be the sender I assigned when using gmail in settings - the "sender" had to be in the approved senders list within your gmail account settings.
Hope that helps.
You will have to use the EMAIL_HOST_USER as the sender because you are going to send the mail from this user account.
Please import your settings in your views.py as mentioned below.
import settings
send_mail(subject, message, settings.EMAIL_HOST_USER, recipients)
I have a page where people can submit an email. It works, but I receive all emails from it saying that they are from myself.
Here's the view:
def signup(request):
if request.method == 'POST': # If the form has been submitted...
form = SignUpForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
subject = form.cleaned_data['subject']
message = form.cleaned_data['message']
sender = form.cleaned_data['sender']
recipients = ['illuminatirebellion#gmail.com']
from django.core.mail import send_mail
send_mail(subject, message, sender, recipients)
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = SignUpForm() # An unbound form
return render_to_response('signup.html', {'form': form,},context_instance=RequestContext(request))
And the settings:
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_HOST_USER = 'illuminatirebellion#gmail.com'
EMAIL_HOST_PASSWORD = 'mypassword'
EMAIL_PORT = 587
MANAGERS = ADMINS
Your usage of send_mail() appears to be correct.
Assuming that Gmail is your SMTP vendor, it seems that Gmail does not support using custom From: email addresses.
Relevant:
Rails and Gmail SMTP, how to use a custom from address
How to change from-address when using gmail smtp server