I've create following form:
class ContactForm(forms.Form):
full_name = forms.CharField(required=False)
email = forms.EmailField()
message = forms.CharField(widget=forms.Textarea(attrs={'class':'special', 'size': '40'}))
But when I add data in Message field with some data it isn't coming up in my email associated with this form with settings mentioned in Settings.py. But full_name and email is coming up fine.
My view is:
def contact(request):
title = "Contact Us"
form = ContactForm(request.POST or None)
if form.is_valid():
form_email = form.cleaned_data.get('email')
form_message = form.cleaned_data.get('message')
form_full_name = form.cleaned_data.get('full_name')
subject = "Site Contact Form"
from_email = settings.EMAIL_HOST_USER
to_email = [from_email, myemail#gmail.com']
contact_message = "%s: %s via %s"%(form_full_name, form_message, form_email)
html_template = "<h1>Hello There</h1>"
send_mail(subject, contact_message, from_email, to_email, html_message=html_template, fail_silently=True)
context = {
"form":form,
"title": title
}
return render(request, 'contact/form.html', context)
Also I need to know what would be the best option to create some form to recieve information directly to my email. Should I use models based form or simple form without models? Please advise as my message field text is not coming up in email but Name and email is coming up fine.
Try this,
message = forms.CharField(widget=forms.TextInput(attrs={'class':'special', 'size': '40'}))
Related
I have a view that has a simple "save and add another" functionality, that redirects the user to the same page after submit the form.
View:
def new_planning(request):
form = PlanningForm(request.POST)
if form.is_valid():
form.save()
if 'another' in request.POST:
messages.success(request, ('Success!'))
return redirect('new_planning')
else:
return redirect('list_planning')
return render(request, 'pages/planning/new_planning.html', context={
'form': form,
})
Form:
class PlanningForm(forms.ModelForm):
accountplan = ModelChoiceField(
queryset=AccountsPlan.objects.filter(active=True).order_by('code'),
)
month = forms.DateField(
required=True,
error_messages={'required': '', },
)
amount = forms.DecimalField(
max_digits=9,
decimal_places=2,
required=True,
validators=[
error_messages={'required': '', },
)
class Meta:
model = Planning
fields = '__all__'
The function works as expected and after the submit, the same page is rendered with a blank form. What I want is to keep just the "amount" field blank and keep the data typed in the "accountplan" and "month" fields. Is there a way to do this?
I read about instance in the docs, but it doesn't seem to be what I looking for, since I don't want to get the data from the database (if that's possible), but simply keep the last inputs typed in both fields.
If you rewrite the "ModelForm" to a "Model" class, you can get the values of the posted datas, and can be rendered to the page.
For example:
# views.py
def ContactPageView(request):
if request.method == "POST":
email = request.POST.get('email')
message = request.POST.get('message')
message_element = ContactFormObject(email=email, message=message)
message_element.save()
else:
name, message = '', ''
form_data = name, message
return render(request, 'contact.html', {'form_data': form_data})
# models.py
class ContactFormObject(models.Model):
email = models.CharField(max_length=100) #....
ModelForm is more comfortable, but I don't recommend it if you have extra 10 minutes to code some HTML in order to the possibilities of more customization.
I need to send an email to the users associated to the Shop when a purchase is done in the shop. If two users was associated for two of them also email should go.
Note: shop_user is the feild name and it is a many to many feild
def generate_invoice(request):
if request.user.is_authenticated:
billingshop = shop.objects.all()
Product = product.objects.all()
if request.method == 'POST':
form = Invoicing(request.POST)
if form.is_valid():
user = form.save(commit=False)
Billing_shop = form.cleaned_data['Billing_shop']
Supplier = form.cleaned_data['Supplier']
Payment_mode = form.cleaned_data['Payment_mode']
Upi_transaction_id = form.cleaned_data['Upi_transaction_id']
products = form.cleaned_data['Product']
Quantity = form.cleaned_data['Quantity']
shoping_product = product.objects.filter(Product_name= products).first()
sub_total = shoping_product.product_price * Quantity
user.Gst = (18 / 100)*sub_total
user.Price = sub_total + user.Gst
user.save()
shoppingcartuser= shop.objects.get(shop_name= Billing_shop) // Match the shop name
shoppingcartemails= shoppingcartuser.shop_users.all().values_list('email', flat=True) // Retriving the email address associated with the shopname in the feild name shop_users.
date = datetime.today()
html_content = render_to_string("invoices/invoice_email.html", {'title':"test mail","date":date,"invoiceuser":Billing_shop,"supplier":Supplier,"payment":Payment_mode,"transactionid":Upi_transaction_id})
text_content = strip_tags(html_content)
email = EmailMultiAlternatives(
"Congratulations! Invoice generated successfully",
text_content,
settings.EMAIL_HOST_USER,
[shoppingcartemails] // this place is the to email
)
email.attach_alternative(html_content,"text/html")
email.send()
messages.success(request, 'Registration successful.')
return redirect('home')
else:
form = Invoicing()
return render(request, 'invoices/create_invoice.html', context={'form': form,'shop':billingshop,'Product':Product})
else:
messages.error(request, 'Please login into your account.')
return render("login")
The feild shop_users consists of two mail addresses and i am facing this error in the browser. I don't know how to rectify it.
Invalid address; only <QuerySet > could be parsed from "<QuerySet ['email1#gmail.com', 'email2#gmail.com']>"
Can someone help me please. I need to send email for both of the email id.
you should put it on a list, and it will not be necessary the [ ]
shoppingcartemails= list(shoppingcartuser.shop_users.all().values_list('email', flat=True))
email = EmailMultiAlternatives(
"Congratulations! Invoice generated successfully",
text_content,
settings.EMAIL_HOST_USER,
shoppingcartemails
)
So my model, form, and view are working mostly. View works and sending the email works. The "message" is saved but I cannot get the message_to and message_from to save. It is supposed to save the usernames. I can get everything to save, but cannot get the message saved to the database WITH the to and from usernames. I am trying to only have 1 field in the message. "Content". The to and from should be hidden and auto-populated. I appreciate any other set of eyes on this. Thank you.
'models.py'
class Message(models.Model):
message_content = models.TextField()
message_to = models.ForeignKey(User, on_delete=models.CASCADE, related_name='message_to')
message_from = models.ForeignKey(User, on_delete=models.CASCADE, related_name='message_from')
date_created = models.DateTimeField(default=timezone.now)
unread = models.BooleanField(default=True)
'forms.py'
class MessageSellerForm(forms.ModelForm):
class Meta:
model = Message
'views.py'
def ad_detail(request, *args, **kwargs):
template_name = 'x_ads/ad_detail.html'
ad = get_object_or_404(Ad, pk=kwargs['pk'])
ad.increment_view_count()
if request.method == 'POST':
message_form = MessageSellerForm(data=request.POST)
message_form.message_from = request.user.username
message_form.message_to = ad.creator.username
if message_form.is_valid():
subject = 'Message about your ad. ' + ad.title
from_email = request.user.email
to_email = ad.creator.email
message = 'You have a message about one of your ads waiting for you!'
send_mail(subject=subject, message=message, from_email=from_email,
recipient_list=[to_email], fail_silently=False)
messages.success(request, your message has been sent.')
message_form.save()
return HttpResponseRedirect(request.path_info)
else:
message_form = MessageSellerForm()
return render(request, template_name, {'ad': ad, 'message_form': message_form})
I think I see what you're trying to do there, but there are other ways that I think will be a bit easier.
https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/#the-save-method
You could instead:
# create the django object in memory, but don't save to the database
message = message_form.save(commit=False)
message.message_from = request.user.username
message.message_to = ad.creator.username
# now save it to the database
message.save()
If you do that you won't need the assignments to the message form further up:
message_form.message_from = request.user.username
message_form.message_to = ad.creator.username
EDIT
You might also need to modify your MessageSellerForm to not include the message_from and message_to fields so that validation will work. That's OK because you know that you'll be assigning the right values to those fields after form validation but before saving to the database.
I want to have my contact form send to different emails based on the department the user chooses. Right now I'm just trying to print the department the user has picked but I'd like to set up some conditionals to send to different emails based on the department value.
This gives me KeyError at /contact/ 'DEALERSHIP ENQUIRIES'
forms.py
from django import forms
class ContactForm(forms.Form):
DEPARTMENT_CHOICES = (
('SALES ENQUIRIES', 'Sales Enquiuries'),
('DEALERSHIP ENQUIRIES', 'Dealership Enquiuries'),
('JOB ENQUIRIES', 'Job Enquiuries'),
('ALL OTHER QUESTIONS', 'All Other Questions'),
)
name = forms.CharField(max_length=255)
sender_email = forms.CharField(max_length=255)
phone = forms.CharField(max_length=255)
subject = forms.CharField(max_length=255)
department = forms.ChoiceField(choices = DEPARTMENT_CHOICES, widget=forms.Select(), required=True)
message = forms.CharField(required=True, widget=forms.Textarea(attrs={'rows': 8}))
views.py
def contact_view(request):
form = ContactForm
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
subject = f'Message from {form.cleaned_data["name"]}'
message = form.cleaned_data["message"]
sender = form.cleaned_data["sender_email"]
phone = form.cleaned_data["phone"]
department = form.cleaned_data["department"]
print(form.cleaned_data[department])
context = {
"form": form,
}
return render(request=request, template_name='main/contact.html', context=context)
I've built a simple form that should send an email on form submit, as well as save to a table in the database. I've done this by following different tutorials, as I am still learning Django. At the moment, it should be configured to output the email to the console rather than actually send an email, as per the tutorial I followed.
I don't get any errors and the console shows a HTTP 200 success code when the form is posted, so it seems to be working, but since nothing is saved and no email is printed to the console, I'm not sure what is going on.
My models.py:
from __future__ import unicode_literals
from django.db import models
from multiselectfield import MultiSelectField
class Booking(models.Model):
timeslot = (
('EM', 'Early Morning'),
('LM', 'Late Morning'),
('EA', 'Early Afternoon'),
('LA', 'Late Afternoon'),
)
services = (
('gutters', 'Gutter Cleaning'),
('windows', 'Window Cleaning'),
('decks', 'Deck Staining'),
('painting', 'Painting'),
)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
email = models.CharField(max_length=30)
phone = models.CharField(max_length=30)
booking_time = models.CharField(max_length=1, choices=timeslot)
selected_services = MultiSelectField(choices=services)
The relevant part of my views.py:
def booking_new(request):
form_class = BookingForm
# new logic!
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
first_name = request.POST.get(
'first_name'
, '')
last_name = request.POST.get(
'last_name'
, '')
email = request.POST.get(
'email'
, '')
phone = request.POST.get(
'phone'
, '')
booking_time = request.POST.get(
'booking_time'
, '')
selected_services = request.POST.get(
'selected_services'
, '')
form_content = request.POST.get('content', '')
template = get_template('email_template.txt')
context = {
'first_name': first_name,
'last_name': last_name,
'email': email,
'form_content': form_content,
}
content = template.render(context)
email = EmailMessage(
"New contact form submission",
content,
"Your website" +'',
['youremail#gmail.com'],
headers = {'Reply-To': contact_email }
)
email.send()
form.save()
return redirect('booking_new')
return render(request, 'home/booking_edit.html', {
'form': form_class,
})
My forms.py:
from django import forms
from .models import Booking
class BookingForm(forms.ModelForm):
class Meta:
model = Booking
fields = ('first_name', 'last_name', 'email', 'phone', 'booking_time', 'selected_services')
And the end of my settings.py:
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
DEFAULT_FROM_EMAIL = 'testing#example.com'
EMAIL_HOST_USER = ''
EMAIL_HOST_PASSWORD = ''
EMAIL_USE_TLS = False
EMAIL_PORT = 1025
I'm not getting any errors about missing imports or URLs or templates etc, so I think I have included all the relevant info. As far as I can see everything is configured correctly.
Why when my form is submitted is no email sent, and no record saved to the database?
the console shows a HTTP 200 success code
This suggests that the form is not valid. If the form was valid, you would redirect after sending the email, so you would see status code 302.
In the view, you should pass the form to the template instead of the form class. That way you should see any errors rendered in the form template (assuming you use {{ form }}).
if request.method == 'POST':
form = form_class(data=request.POST)
...
else:
form = form_class() # Blank form for GET request
return render(request, 'home/booking_edit.html', {
'form': form,
})
You may also find it useful to add print statements (e.g. print(form.is_valid()), print(form.errors). The output in the console will help you debug what is happening when the view runs.