Reputation: 3056
Does anyboy know how do I set the desired mimetype when using TemplateView, as in:
urlpatterns = patterns('',
url(r'^test\.txt$', TemplateView.as_view(template_name='staticpages/test.html')),
In this case, I want to set the mimtype as "text/plain"
Upvotes: 31
Views: 10817
Reputation: 2050
A simple example of how change content type of a TemplateView:
#views.py
from django.views.generic import TemplateView
class HomeView(TemplateView):
template_name = "home/index.html"
content_type = 'text/html'
# urls.py
url(r'^home/$', HomeView.as_view(), name='home_page'),
Upvotes: 1
Reputation: 2849
TemplateView accepts a content_type argument.
Coping example from @Meilo
urlpatterns = patterns('',
url(r'^test\.txt$', TemplateView.as_view(template_name='staticpages/test.html', content_type='text/plain')),
I think that just calling TemplateView.as_view() is not posible but maybe i missed it (from the source), but you can do your own class
class TextTemplateView(TemplateView):
def render_to_response(self, context, **response_kwargs):
response_kwargs['content_type'] = 'text/plain'
return super(TemplateView, self).render_to_response(context, **response_kwargs)
You can take a look to:
django.template.response => TemplateResponse
django.views.generic.base => TemplateView
And if you need something more dynamic:
from django.utils.decorators import classonlymethod
class ContentTypeTemplateView(TemplateView):
@classonlymethod
def as_view(cls, content_type='text/plain', **initargs):
setattr(cls, 'content_type', content_type)
return super(ContentTypeTemplateView, cls).as_view(**initargs)
def render_to_response(self, context, **response_kwargs):
response_kwargs['content_type'] = self.content_type
return super(ContentTypeTemplateView, self).render_to_response(context, **response_kwargs)
urlpatterns = patterns('',
url(r'^$', ContentTypeTemplateView.as_view(content_type='text/plain',
template_name='staticpages/test.html'),
name='index'),
)
from django.core.exceptions import ImproperlyConfigured
class ContentTypeMixin(object):
content_type = None
def render_to_response(self, context, **response_kwargs):
if not self.content_type:
raise ImproperlyConfigured(
"MimeTypeMixin rquires a definition of content_type")
response_kwargs['content_type'] = self.content_type
return super(ContentTypeMixin, self).render_to_response(context,
**response_kwargs)
class MyTxtView(ContentTypeMixin, TemplateView):
content_type = 'text/plain'
....
Upvotes: 44
Reputation: 138
url(r'^test/(?P<template>.*)', lambda request, template: TemplateView.as_view(template_name=template)(request)),
Upvotes: 0
Reputation: 184
I know that you ask for setting a content type with TemplateView, but I will give you different answer which I think that will be more clean and can be used in Django versions lower than 1.5.
url(r'^robots\.txt$', 'django.shortcuts.render', kwargs={
'template_name': 'robots.txt',
'content_type': 'text/plain',
})
With this approach you don't need to import anything or to subclass TemplateView
and make ugly overwrites of some methods. You can simply use the old technique with function based views.
Upvotes: 4
Reputation: 479
I know this is solved for 1.5, but the application I am working in is 1.4.
I had an issue with two url patterns in a row using sacabuche's answer:
url(r'^playlist1\.m3u$', ContentTypeTemplateView.as_view(template_name='playlist1.m3u', content_type='audio/x-mpegurl')),
url(r'^playlist2\.pls$', ContentTypeTemplateView.as_view(template_name='playlist2.pls', content_type='audio/x-scpls'))
I found playlist1 would return the correct template, but with playlist2's content type! Playlist2 was ok. Adding a 3rd url pattern with a content-type of 'foo' would cause all playlist views to return with content-type 'foo'.
I ended up using the render method instead with good results:
urls:
url(r'^playlist1\.m3u$', 'content_type_to_template', {'template_name': 'playlist1.m3u', 'content_type': 'audio/x-mpegurl'}),
url(r'^playlist2\.pls$', 'content_type_to_template', {'template_name': 'playlist2.pls', 'content_type':'audio/x-scpls'})
views:
from django.shortcuts import render
def content_type_to_template(request, template_name='', content_type='text/plain'):
return render(request, template_name, content_type=content_type)
Upvotes: 1
Reputation: 3418
In Django 1.5 the content_type argument in the TemplateView adds the same functionality that was in the function-based view before. That makes it easier to set the desired mimetype:
urlpatterns = patterns('',
url(r'^test\.txt$', TemplateView.as_view(template_name='staticpages/test.html', content_type='text/plain')),
Upvotes: 19
Reputation: 11
The best way to do it is to subclass TemplateView
and override the render_to_response()
method:
class StaticPagesTest(TemplateView):
template_name = 'staticpages/test.html'
def render_to_response(self, context, **kwargs):
return super(StaticPagesTest, self).render_to_response(context,
mimetype='text/plain', **kwargs)
Upvotes: 1
Reputation: 91595
If you don't want to extend the TemplateView, you can extend the TemplateResponse to set the mimetype:
from django.template.response import TemplateResponse
class TextResponse(TemplateResponse):
def __init__(self, *args, **kwargs):
kwargs['mimetype'] = 'text/plain'
return super(TextResponse, self).__init__(*args, **kwargs)
Then pass it as the template_class to the TemplateView
urlpatterns = patterns('django.views.generic.simple',
(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt', response_class=TextResponse)),
)
Upvotes: 1