Django - manually build HttpResponse, but want to use a template too - python

When returning an HttpResponse object with render_to_response you can provide a template and it will use that template and fill in all the {{ variables }} you've set within your template.
If I want to build my HttpResponse object manually, is it possible to still use one of my templates in my template directory?

Using render_to_string, you will get rendered string. You can pass the returned string to the HttpResponse.
from django.template.loader import render_to_string
...
rendered = render_to_string('my_template.html', {'foo': 'bar'})
response = HttpResponse(rendered)

Yes - you can use Django's template loader to load your template as a Template object, and then render it to a string, which you pass to HttpResponse:
from django.template import Template, Context
from django.template.loader import get_template
def my_view(request):
temp = get_template('/path/to/template.html')
result = temp.render(Context({'context': 'here'})
return HttpResponse(result)
EDIT
Just noticed #falsetru's answer above - that's probably a better and shorter way!

Related

Django include templates in markdown

I have Django templates written in Markdown. I'd like to implement template tag to include rendered markdown.
{% include_md 'mytemplate.md' }
I wrote template tag to render my template:
import markdown
from django.template import Library, loader, Context
#register.simple_tag(takes_context=True)
def include_md(context, template_name):
t = loader.get_template(template_name)
return t.render(Context({
#...
}))
but I need to put somewhere in the middle of my function something like:
markdown.markdown(template_content)
Unfortunately, template loader doesn't return content of template. So what is a best way to achieve rendering? I woudln't like to implement my own opening template methods with open().
Django provides a convenience method render_to_string for situations like this:
from django.template.loader import render_to_string
#register.simple_tag(takes_context=True)
def include_md(context, template_name):
template = render_to_string(template_name, context)
return markdown.markdown(template)

What is the difference between render() of DjangoTemplates class and render() method found in django.shortcuts module?

I am trying to learn Django. I am creating a small applicationt to understand its basic functionalities. In views.py of a django app, some tutorials use render() from template while others use render() from django shortcuts module.
For instance, in views.py
from django.shortcuts import render
def home(request):
context = {}
template = "app/add_item.html"
return render(request, template,context)
and yet others,
from django.http.response import HttpResponse
from app.models import Items # this is the model
def home(request):
item_list = Items.objects.order_by('-item_name')
template = loader.get_template('app/add_item.html') # could be index.html as well
context = {
'item_list': item_list,
}
return HttpResponse(template.render(context, request))
What is the difference between render() method of DjangoTemplates class and render() method found in django.shortcuts module? Which one should I prefer and why?
django.shortcuts.render is, as its name implies, a shortcut for returning a rendered template as a response from a view. Its use is rather limited to that context. It takes an HttpRequest instance as its first argument and its main purpose, per the docs, is to
combine a given template with a given context dictionary and returns an HttpResponse object with that rendered text.
Importantly, this selects a template by name. It is intended to select a template for rendering and returning as a response.
Template.render is part of the low-level template API and takes the single template, represented by that object, and renders it to a string.
Importantly, this takes only the template already represented by your object. It has no mechanism for discovering another template to render.
Generally, the shortcut version is the most useful, as quite often you want to return a rendered template as a response from your views. This is the whole reason it exists.

django: return string from view

I know this is a simple question, sorry. I just want to return a simple string, no templates.
I have my view:
def myview(request):
return "return this string"
I don't remember the command. Thanks
According to the documentation:
A view function, or view for short, is simply a Python function that
takes a Web request and returns a Web response.
Each view function is responsible for returning an HttpResponse
object.
In other words, your view should return a HttpResponse instance:
from django.http import HttpResponse
def myview(request):
return HttpResponse("return this string")
If you create a chat-bot or need this response on post request for confirmation - you should add decorator, otherwise Django block post requests.
More info you can find here https://docs.djangoproject.com/en/2.1/ref/csrf/
Also in my case I had to add content_type="text/plain".
from django.views.decorators.csrf import csrf_protect
from django.http import HttpResponse
#csrf_exempt
def Index(request):
return HttpResponse("Hello World", content_type="text/plain")
You can't send directly a string, but you can send a JSON object:
from django.http import JsonResponse
def myview(request):
return JsonResponse({'mystring':"return this string"})
Then process that. With Javascript for example if the page was requested by AJAX:
$.ajax({url: '/myview/', type: 'GET',
data: data,
success: function(data){
console.log(data.mystring);
...
}
})
https://docs.djangoproject.com/en/1.11/ref/request-response/#jsonresponse-objects
we use HttpResponse to render the Data
HttpResponse to render the Text
from django.http import HttpResponse
def Index(request):
return HttpResponse("Hello World")
HttpResponse to render the HTML
from django.http import HttpResponse
def Index(request):
text = """<h1>Hello World</h1>"""
return HttpResponse(text)
urls.py
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('about/',views.aboutview),
path('',views.homeview),
]
views.py
from django.http import HttpResponse
def aboutview(request):
return HttpResponse("<h1>about page</h1>")
def homeview(request):
return HttpResponse("<h1>home page</h1>")
I need to clear the air should someone bump to this in the feature, like wanting to pass any sort of string.
I hard to do the following, starting with the view:
from django.http import HttpResponse
def myview(request):
text = """Visit W3Schools.com!"""
return HttpResponse(text)
Then urls, btw the endpoint here "submit/myview" can be anything
path('submit/myview', views.myview, name='myview'),
the ajax side of things on the template where you want to render this
<div id="demo">
<h2>The XMLHttpRequest Object</h2>
<button type="button" onclick="loadDoc()">Change Content</button>
</div>
<script>
function loadDoc() {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
document.getElementById("demo").innerHTML =
this.responseText;
}
xhttp.open("GET", "myview");
xhttp.send();
}
</script>
According Django documentation Django uses request and response objects to pass state through the system.
When a page is requested, Django creates an HttpRequest object that contains metadata about the request. Then Django loads the appropriate view, passing the HttpRequest as the first argument to the view function. Each view is responsible for returning an HttpResponse object.Do as follows
from django.http import HttpResponse
def myview(request):
text="return this string"
return HttpResponse(text)

Django's nested render_to_response always show content-type

Currently I am trying to create multiple view for one request. For 1 view, I am doing this:
return render_to_response(
"/index/index.html",
{}
)
And now when I try to add a "left" column to index.html, I need to put it on different view (because I need to apply the same technique on other place as well), this is how I do it:
leftCol = direct_to_template(request,settings.viewPath + "/columns/left.html",{})
return render_to_response(
"/index/index.html",
{
'leftColumn': leftCol,
}
The code works well, but the output is not what I expected. The leftCol shows the response header at the beginning of it's output:
"Content-Type: text/html; charset=utf-8"
How do I remove this header? I've been trying to modify the content_type and mimetype in the parameter but it didn't work.
That's because direct_to_template() returns a HttpResponse, not a string. Have you considered using templating functionality, e.g. the {% include %} template tag, or writing a template tag of your own?
If you insist on pre-rendering templates in your view and then combining them in your template, render the template yourself, rather than using direct_to_template(). e.g.
from django.template.loader import get_template
from django.template import RequestContext
def someview(request):
leftCol = get_template(settings.viewPath + "/columns/left.html").render(RequestContext(request)
render_to_response("/index/index.html", {'leftColumn': leftCol})
Use render_to_string (http://docs.djangoproject.com/en/dev/ref/templates/api/#the-render-to-string-shortcut) to get a string back after rendering a template. Alternatively, you can use an {% include %} to include a template in the same context as the current template (but this is still manual). Even better would be to have a base template that you inherit using {% extends 'base.html' %} which will just include common template functionality that you can override at your will using {% block %} and enables you to leave out duplicated template content like a left column.
The 'render_to_response' function returns an HttpResponse object. Instead of returning the object itself, you can return its content attribute to access only the output you want to render.
i.e.
response = render_to_response(
"/index/index.html",
{
'leftColumn': leftCol,
}
return response.content

How to make Django template engine to render in memory templates?

I am storing my templates in the database and I don't have any path to provide for the template.render method.
Is there any exposed method which accepts the template as a string?
Is there any workaround?
Based on the the docs for using the template system:
from django.template import Template, Context
t = Template("My name is {{ my_name }}.")
c = Context({"my_name": "Adrian"})
t.render(c)
Instantiate Template with the string to use as a template.
In Django < 1.8:
from django.template.loader import get_template_from_string
tpl = Template(get_template_from_string("My name is {{ my_name }}."))

Categories