I am using Django to build up my web project. As known that mako and Jinja2 template are faster that the one Django's given, I start finding way to integrate mako and Jinja2 into Django with using the Django's way of render_to_response method. After a lot research, I finally figure out the way to make this happen. However, in my integration, the jmeter's performance is something like Jinja2 (3ms) > Django's template (50ms) > mako (218ms).
If I went wrong with something?....Or pls help to advise some best practice to integrate jinja2 and mako.
Below is the coding ()
Mako2django.py
from django.http import HttpResponse
from django.template import Context
from mako.lookup import TemplateLookup
from mysite.settings import TEMPLATE_DIRS
def render_to_mako(t,c=None,context_instance=None):
path = TEMPLATE_DIRS
makolookup = TemplateLookup(directories=[path],output_encoding='utf- 8',input_encoding='utf-8')
mako_temp = makolookup.get_template(t)
if context_instance:
context_instance.update(c)
else:
context_instance = Context(c)
data = {}
for d in context_instance:data.update(d)
return HttpResponse(mako_temp.render(**data))
Jinja2django.py
from django.http import HttpResponse
from django.conf import settings
from jinja2 import Environment, ChoiceLoader, FileSystemLoader
# Setup environment
default_mimetype = getattr(settings, 'DEFAULT_CONTENT_TYPE')
# Create the Jinja2 Environment
env = Environment(
line_statement_prefix='%',
line_comment_prefix='##',
loader=ChoiceLoader([FileSystemLoader(path) for path in getattr(settings, 'TEMPLATE_DIRS', ())]))
def render_to_string(filename, context={}):
return env.get_template(filename).render(**context)
def render_to_jinja2(filename, context={},mimetype=default_mimetype, request = None):
if request: context['request'] = request
return HttpResponse(render_to_string(filename, context),mimetype=mimetype)
The view.py is similar as below
from draft.jinja2django import render_to_jinja2
def view1(request):
b = "helloworld"
return render_to_jinja2('testjinja.html', context={"test":b})
Starting from Django 1.2 you can create your custom template loader that returns your Template object. Doing that you can make django's render_to_response, render_to_string and counterparts render using your template system.
I am using this one:
https://gist.github.com/972162
It loads Jinja2 templates transparently and falls back to Django templates for admin, contrib and third-party apps.
Related
I'm new to Django and python (infact my first language which I've only been learning for 3 months)
I'm creating this website using Django and I'm not able to go from one page to another using the href tag. it throws at me a 404 error saying "current path didn't match any of these"
This is my code
views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect
from .models import off
# Create your views here.
def homepage(request):
return render(request=request,
template_name='main/home.html',
context={'toll' : off.objects.all})
def secondpage(request):
return render(request = request,
template_name = 'main/next.html')
main/urls.py
from django.urls import path
from . import views
app_name = 'main'
urlpatterns = [
path('',views.homepage,name='homepage'),
path('',views.secondpage,name='secondpage')
]
templates/mains/home.html
<div class="topnav">
Link
Link
Link
</div>
I also request the helper to simply it for me as I wouldn't be able to handle complex and advanced python terminology
Thanks In Advance From a Friend
Arvind
I think you should read this to start with Django.
I am using sites framework with RequestSite (no SITE_ID set) to generate content based on domain. I need to generate sitemaps for each domain with different results but I didnt find a way how to make this two frameworks work together. Is there any way to get Site of the current request in Sitemap? (getting it from SITE_ID config is not an option for me).
Here is an example of what I would like to do:
from django.contrib.sitemaps import Sitemap
from blog.models import Entry
class BlogSitemap(Sitemap):
def items(self, request):
return Entry.objects.filter(is_draft=False, site=request.site)
But its not possible because there is no request in items(). Is there any other way how to filter items in sitemap based on site?
Try following example:
from django.contrib.sitemaps import Sitemap
from django.contrib.sitemaps.views import sitemap
from blog.models import Entry
class BlogSitemap(Sitemap):
_cached_site = None
def items(self):
return Entry.objects.filter(is_draft=False, site=self._cached_site)
def get_urls(self, page=1, site=None, protocol=None):
self._cached_site = site
return super(BlogSitemap, self).get_urls(page=page, site=site, protocol=protocol)
And in urls.py
urlpatterns = [
url('sitemap.xml', sitemap, {
'sitemaps': {'blog': BlogSitemap}
}, name='django.contrib.sitemaps.views.sitemap'),
# ...
# other your urls
]
This should work now. Let me know if you'll have any questions.
I'm trying to implement some JS code in django so anytime i click a button, it returns the current year.. how do i do this
I've tried using some JS events handler in my django based templates
from datetime import datetime
from django.template import Template, Context
from django.http import HttpResponse as toHTML
cont = Context({'dat':datetime.now()})
def say_year(request):
htm = Template("<button onclick='alert({dat})'>click me</button>")
htm = htm.render(cont)
return toHTML(htm)
i'm expecting an alert box showing full datetime.now() methods
I prefer that you do it that way in order to have full control over the template.
1 - make the views.py that way :
from datetime import datetime
from django.template import Template, Context
from django.shortcuts import render
def say_year(request):
context = {
'dat': datetime.now()
}
return render(request, 'mytemplate.html', context)
2- The urls.py should look that way :
from django.contrib import admin
from django.urls import path
from your_app import views
urlpatterns = [
path('admin/', admin.site.urls),
path('my_template/', views.say_year )
]
3- You create a templates folder in the root directory of your project where all your templates will live.
For your question i have create my_template.html and it should be that way :
<button onclick="alert('{{dat}}')">click me</button>
If you have more questions please let me know.
Currently using a REST API and the generic views CreateUpdateDestroy, and my admin display GUI looks like this :
All the sources online that I've followed, tutorials etc get a generic view which looks much nicer.
Here is my views.py:
from rest_framework import generics
from models import Results
from serializers import ResulutsSerializer
class ResultsList(generics.ListAPIView):
queryset = Results.objects.all()
serializer_class = ResultsSerializer
class ResultsDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Results.objects.all()
serializer_class = ResultsSerializer
and urls.py:
from django.urls import path
from main import views
urlpatterns = [
path('results/', views.ResultsList.as_view()),
path('<int:pk>/', views.ResultsDetails.as_view())
]
what am I doing wrong?
It looks like you need to collect your app assets:
$ python manage.py collectstatic
# You can provide option: --settings=<your-settings-file> if you're using custom settings which is not default in manage.py
You will need to configure staticfiles settings in your Django settings module if not already configured – e.g. settings.py. Please follow documentation at:
https://docs.djangoproject.com/en/2.0/howto/static-files/
https://docs.djangoproject.com/en/2.0/ref/contrib/staticfiles/
If you are developing locally:
You should set DEBUG=True in your Django Settings Module (i.e. normally settings.py)
I want to add the mobile version to my site, so I need to change the template path dynamically to get the mobile template dir or the desktop dir.
As the TEMPLATE_DIRS is deprecated since version 1.8, I tried to change the DIRS option of a DjangoTemplates backend, but it didn't work.
As I had the same challenge I post my code here. I am using the get_flavor from django_mobile to detect what to show and I wanted to use the standard admin directories (as installed) for django_admin_bootstrapped and the regular django admin. In addition I wanted to only interfere the loader with admin pages and not with regular pages - in the latter case the loader does nothing.
So this works for me:
import os.path
from django.template.loaders.base import Loader
from django.template.loader import LoaderOrigin
from django.template import TemplateDoesNotExist
from django_mobile import get_flavour
class Myloader(Loader):
is_usable = True #this line is necessary to make it work
def load_template_source(self, template_name, template_dirs=None):
path_split = template_name.split("/")
if not u'admin' in path_split:
raise TemplateDoesNotExist
template_short_name = path_split[-1]
if get_flavour() == "mobile":
basepath = r'/path/to/django_admin_bootstrapped/templates/admin'
path = os.path.join(basepath,template_short_name)
else:
basepath = r'/path/to/django/contrib/admin/templates/admin'
path = os.path.join(basepath,template_short_name)
try:
with open(path,"r") as f1:
template_string = f1.read()
except IOError:
raise TemplateDoesNotExist
template_origin = LoaderOrigin(template_short_name, self.load_template_source, template_name, template_dirs)
return (template_string, template_origin)
If you want to distinguish the template path by something different e.g. by the name in the url you need to replace the "if get_flavour()=="mobile" " by looking for something inntemplate_name.