I want to send mail to many users using django sendmail.
I am using orm in sqlite3 to get the list of recipients stored in db.
However, the orm result includes 'queryset', so mail cannot be sent
Is there a way to exclude 'queryset' from orm results?
as-is
I want
views.py
def send_form(request):
if request.method == 'POST':
selected_target = request.POST['target']
target = contact.objects.filter(target=selected_target).values_list('email')
return render(request, 'view/send_form.html', {'target': target})
def send_success(request):
if request.method == 'POST':
subject = request.POST['subject']
recipient = request.POST['email']
message = request.POST['message']
send_mail(
subject,
message,
recipient,
[recipient],
fail_silently=False,
)
return render(request, 'view/send_success.html')
send result
Queryset returns to you all (many) of applicable results, if you want only one email, instead of filter use get,
target_email = contact.objects.get(target=selected_target).email
but with queryset (many emails) you can send to each email in a list of queryset
target_emails = contact.objects.filter(target=selected_target)
for each_email in target_emails:
target_email = each_email.email
#this will output your needed email
print(target_email)
#and later do logic with target_email to send mail on it
Related
I am trying to send an email to all registered users in Django Allauth, but when I try to get a list of all users' emails and send it via the send_mail() method, I get an error :
too many values to unpack (expected 2)
When I manually specify the mail in the recipient_list list, then everything works. But I need it to be automatically sent to the emails of all users.
Tried to do through :
def email(request):
cleaned_data = super().clean()
title = cleaned_data.get('articles_title')
message = cleaned_data.get('articles_text')
recipient_list = User.objects.get('email')
email_from = 'mymail'
send_mail(title, message[:50], email_from, recipient_list)
return title, message
or iterate through the for loop:
def email(request):
cleaned_data = super().clean()
title = cleaned_data.get('articles_title')
message = cleaned_data.get('articles_text')
mails = User.objects.get('email')
recipient_list = []
for i in mails:
recipient_list.append(i)
email_from = 'mymail'
send_mail(title, message[:50], email_from, recipient_list)
return title, message
But nothing helps, does someone know some alternative method?
I am trying to add messaging functionality to my web app made in Django.
So far, I have managed to successfully send and receive messages from user to user.
But, now I have been stuck at showing all the conversation lists to the inbox.html page of the logged user.
I have tried different approaches that I can think of but can not get the expected result.
models.py
class Messaging(models.Model):
sender = models.ForeignKey(User, on_delete=models.CASCADE, related_name='sender')
receiver = models.ForeignKey(User, on_delete=models.CASCADE, related_name='receiver')
message_text = models.TextField(max_length=360, verbose_name='Write Message')
message_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'{self.sender}\'s Message to {self.receiver}'
viwes.py
Function to send and receive messages from user to user
#login_required
def messageview(request, user_name):
sender_user = request.user
receiver_user = User.objects.get(username=user_name)
message_list = Messaging.objects.filter(sender=sender_user, receiver=receiver_user).order_by('message_date') | \
Messaging.objects.filter(receiver=sender_user, sender=receiver_user).order_by('message_date')
if request.method == 'POST':
msg_text = request.POST.get('msg_text')
messaging = Messaging()
messaging.sender = sender_user
messaging.receiver = receiver_user
messaging.message_text = msg_text
messaging.save()
return redirect(request.META['HTTP_REFERER'])
context = {
'sender_user': sender_user,
'receiver_user': receiver_user,
'message_list': message_list,
}
return render(request, 'message.html', context)
Now I want to create an inboxview in views.py that will render all the conversation of the logged user.
Suppose I have two users in the database A and B, they have exchange 4 messages between them. What I want is to show the conversation as a list, which is in this case only one. For example, the logged user is A, he exchanges messages with user B and C. The inbox will show two rows. When user A clicks on either of the rows, he will be taken to the details message page corresponding to the user. It is kinds of like WhatsApp or messenger. I hope I can explain.
Edited: Added example image for better understanding
I am able to do this:
I need help to do this:
Please guide me the way.
You could try something like this.
This view will query the Messaging model and get all entries where sender or receiver is the logged in user.
#login_required
def inbox(request, user):
# Get all the records where either sender OR receiver is the logged in user
messages = Messaging.objects.filter(sender=request.user) | Messaging.objects.filter(receiver=request.user)
context = {'messages': messages}
return render(request, 'inbox.html', context)
You can add any extra lines of code to the above code that suits your requirements.
inbox.html
{% for message in messages %}
# You can show your message details here
{% endfor %}
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 created a site where my techs submit their inventory using model forms. Everything is working as intended but I would like to add the function of sending the whole form as an email when they submit their inventory. This would allow for my inventory team to verify counts without having to log in and check the website.
Here is my view.py I know it works if I remove the email bits and saves to my models. Currently returns an error:
'dict' object has no attribute 'splitlines'
form = Inventory_Form()
if request.method == 'POST':
form = Inventory_Form(request.POST)
tech_field = form.save(commit=False)
tech_field.technician = request.user
tech_field.save()
if form.is_valid():
form.save()
name = form.cleaned_data['initials_date']
from_email = 'operations#imbadatthis.com'
subject = 'Weekly Inventory', form.cleaned_data['initials_date']
message = form.cleaned_data
try:
send_mail(subject, message, from_email, ['myemail#n00b.com'], name)
except BadHeaderError:
return HttpResponse('Invalid header found.')
return response, redirect('inventory_submitted')
return render(request, 'inventory.html', {'form': form})
Would it be better to save the form to a csv then attach it as an email? I looked at this and also had issues with that part.
I guess the error is raised at the send_mail because of
message = form.cleaned_data
Because this is a dict and the send_mail from django expects the message to be a string.
You have to convert the dict to a string.
Maybe this helps to make a nice looking email. (documentation)
I'm sending a form. So if it's valid i'm setting a variable message with a message. So if the form is valid, I would like to redirect to another view but also pass the message variable. It should be a syntax issue.
On successful submission, it redirects to a view with a url membership/enroll/studies.views.dashboard which of course is wrong.
views.py
def enroll(request):
user = request.user
if request.method == 'POST':
form = SelectCourseYear(request.POST)
if form.is_valid():
student = form.save(commit=False)
student.user = request.user
student.save()
message = 'Successfully Enrolled'
return redirect('studies.views.dashboard', {'message': message,})
else:
form = SelectCourseYear()
return render(request, 'registration/step3.html',)
Consider making use of sessions to store arbitrary data between requests: https://docs.djangoproject.com/en/dev/topics/http/sessions/
request.session['message'] = 'Successfully Enrolled'
Alternatively, if you just want to display a message to the user, you might be happy with the contrib.messages framework: https://docs.djangoproject.com/en/dev/ref/contrib/messages/
from django.contrib import messages
messages.success(request, 'Successfully Enrolled')
Based on your use case above, I'm guessing that contrib.messages is more appropriate for your scenario.