Use Parts of a Template file in Jinja 2 - python

So I want to create a send email function using Templates with Jinja 2.
My specific Issue is that I want to create one template for an email which contains both the subject and the body of the email. For example my template can look like
Subject: This is the Subject
Body: hello I am the body of this email
but I need the subject and body to be saved in different variables to be passed to the sendmail function. My question is , how can I use a single template file and render parts of it in different variables.

You can load a Template, rather than rendering it by using Jinja2's Environment.get_or_select_template method on Flask.jinja_env. Once you have the template, you can access the template's blocks if you don't render it:
some-email.html
{% block subject %}This is the subject: {{ subject_details }}{% endblock %}
{% block body %}
This is the body.
Hello there, {{ name }}!
{% endblock %}
email_handler.py
def generate_email(template_name, **render_args):
"""Usage:
>>> subject, body = generate_email(
'some-email.html',
subject_details="Hello World",
name="Joe")
"""
app.update_template_context(render_args)
template = app.jinja_env.get_or_select_template(template_name)
Context = template.new_context
subject = template.blocks['subject'](Context(vars=render_args))
body = template.blocks['body'](Context(vars=render_args))
return subject, body
def send_email(template_name, **render_args):
subject, body = generate_email(template_name, **render_args)
# Send email with subject and body

Related

How to specify a template for a Snippet in a StreamField when using SnippetChooserBlock

I want to use a snippet in a StreamField:
#register_snippet
class Advert(models.Model):
url = models.URLField(null=True, blank=True)
text = models.CharField(max_length=255)
def __str__(self):
return self.text
class MyPage(Page):
body = StreamField([('Snippet', SnippetChooserBlock(
target_model='web.Advert')])
my_page.html:
{% for block in page.body %}
{% include_block block %}
{% endfor %}
However, when rendering the Advert it renders only the str representation of self.text. How can I specify a template layout for the snippet block, e.g. like a StructBlock?
There is no documentation for SnippetChooserBlock.
Like all block types, SnippetChooserBlock accepts a template argument that specifies the path to a template to render for that block:
class MyPage(Page):
body = StreamField([('Snippet', SnippetChooserBlock(
target_model='web.Advert', template='blocks/advert.html')])
Within that template, the snippet instance is available as the variable value:
<div class="advert">
{{ value.text }}
</div>

Show data from database (python) in HTML

I want to show the RandomId which is saved in database in my HTML, but I am not sure how to do it. Anyone know how to do it?
Here is my html
</script>
<button onclick="myFunction()"><input type="submit" value="Place Order"></button>
<script>
function myFunction() {
alert("Order has been placed in the kitchen \n Your order ID is
{{% random_id %}}")
}
</script>
here is my views.py
RandomId = request.POST.get("RandomId")
RandomId = get_random_string(length=5) #get random string id
#RandomId = request.POST.get("RandomId")
customerOrder = CustomerOrder(Table_Num=Table_Num , Food=Food, Quantity=Quantity, Message=Message, RandomId=RandomId) #get data into the CustomerOrder db
customerOrder.save() #save data into db
random_id = CustomerOrder.objects.all()
#order_summary = CustomerOrder.objects.filter(Table_Num = request.Table_Num)
#order_summary = CustomerOrder.objects.filter(Table_Num = 15)
return render(request, 'restaurants/customer_page.html', {'random_id': random_id}) #return customer page
here we go
in your html
{% for id in random_id %}
{{ id }}
{% endfor %}
Please shorten your code to the relevant parts. And split up your code into different sections to make it easier to read. Like
template:
<p>Some html here </p>
view:
def my_view(request):
# things that happen here
Additionally your code defines RandomId twice and you seem to be inserting uncleaned data into your database. Use forms, use form.is_valid(), provide your model information, and double check when to use {{ something_here }} and {% something_else_here %}. Hint: {{ variable }}, and {% if variable == 'hello world' %}.

Django autoescape is not working in render_to_string(template)?

I am drafting an email template to users when they successfully updated their passwords.
I used {{ autoescape off }} in the template, which is rendered by using render_to_string().
However, the email content shows the HTML angle brackets directly like this:
Hi <span style='color:blue'>user! </span>
Your password is updated successfully!
I am using Django2.0 and my code looks like this:
views.py
from django.core.mail import send_mail
from django.template.loader import render_to_string
def sendmail(request, title)
email_title = title
email_content = render_to_string('template.html',{'username':request.user.username})
recipient = request.user.email
send_mail(
email_title,
email_content,
'myemail#email.com',
[recipient,],
)
template.html
{{ autoescape off}}
Hi <span style='color:blue'>user! </span>
Your password is updated successfully!
{{ endautoescape }}
Is there anything wrong with my code?
Otherwise, is autoescape always on while using render_to_string()?
This has nothing to do with autoescape, which is for rendering variables (it is also a template tag, so you use it with {% autoescape off %}, not {{ autoescape off }}). It is doing nothing at all in your current template.
Your issue is that you're trying to put HTML into the plain text body of an email.
send_mail expects a plain text message body. If you want to have a HTML body then you need to supply a html_message argument:
send_mail(
email_title,
'', # Empty plain text body - not recommended and you should supply a plain text alternative
'myemail#email.com',
[recipient,],
html_message=email_content, # This will render as HTML
)

Django Forms : Make some text sent by form to email appear bold

Quick question. If I have a form that sends to email, is there a way to make some of the sent text show up bold in the email?
In Django 1.7, send_mail() accepts an html_message argument:
If html_message is provided, the resulting email will be
a multipart/alternative email with message as the text/plain content
type and html_message as the text/html content type.
Example:
send_mail('Subject', 'Content', 'sender#example.com', ['nobody#example.com'],
html_message='This is <b>HTML</b> Content')
For Django<1.7, you can either use a solution suggested here, or use a third-party, like django-email-html.
Also, there is another third-party package that you should consider using - django-mail-templated. It basically allows you to describe your email messages in django templates. Additionally, it allows to send html messages defined in html block in the template.
For example:
create a template
{% block subject %}
Email subject
{% endblock %}
{% block body %}
This is a plain text.
{% endblock %}
{% block html %}
This is <b>HTML</b> Content.
{% endblock %}
and send it:
from mail_templated import send_mail
send_mail('my_template.tpl', {}, from_email, [user.email])
Hope that helps.

how to render only part of html with data using django

I am using ajax to sort the data which came from search results.
Now I am wondering whether it is possible to render just some part of html so that i can load this way:
$('#result').html(' ').load('/sort/?sortid=' + sortid);
I am doing this but I am getting the whole html page as response and it is appending the whole html page to the existing page which is terrible.
this is my views.py
def sort(request):
sortid = request.GET.get('sortid')
ratings = Bewertung.objects.order_by(sortid)
locations = Location.objects.filter(locations_bewertung__in=ratings)
return render_to_response('result-page.html',{'locs':locations},context_instance=RequestContext(request))
how can I render only that <div id="result"> </div> from my view function? or what am I doing here wrong?
From what I understand you want to treat the same view in a different way if you receive an ajax request.
I would suggest splitting your result-page.html into two templates, one that contains only the div that you want, and one that contains everything else and includes the other template (see django's include tag).
In your view then you can do something like the following:
def sort(request):
sortid = request.GET.get('sortid')
ratings = Bewertung.objects.order_by(sortid)
locations = Location.objects.filter(locations_bewertung__in=ratings)
if request.is_ajax():
template = 'partial-results.html'
else:
template = 'result-page.html'
return render_to_response(template, {'locs':locations},context_instance=RequestContext(request))
results-page.html:
<html>
<div> blah blah</div>
<div id="results">
{% include "partial-results.html" %}
</div>
<div> some more stuff </div>
</html>
partial-results.html:
{% for location in locs %}
{{ location }}
{% endfor %}

Categories

Resources