I want to generate a PDf of a django template / view; that uses templatetags etc.
From django-wkhtmltopdf's documentation:
from django.conf.urls.defaults import url, patterns
from wkhtmltopdf.views import PDFTemplateView
urlpatterns = patterns('',
url(r'^pdf/$', PDFTemplateView.as_view(template_name='my_template.html',
filename='my_pdf.pdf'), name='pdf'),
)
Or they say in your own view:
from wkhtmltopdf.views import PDFTemplateView
class MyPDF(PDFTemplateView):
filename = 'my_pdf.pdf'
template_name = 'my_template.html'
cmd_options = {
'margin-top': 3,
}
If this was my view:
def download_report(request):
vends = Vends.objects.all()
return render(request, 'report_template.html', {'vends':vends})
How would I generate a report of this VIEW as its rendered? Not just the template, because that would be useless?
You can use PDFTemplateRespone instead of render_to_response.
from wkhtmltopdf.views import PDFTemplateResponse
Then you can do something like this:
def pdf(request, pk):
context = RequestContext(request)
template = 'test.html'
context = {
'variable1': variable1,
'variable1': variable1,
'variable1': variable1,
'variable1': variable1
}
return PDFTemplateResponse(request=request, cmd_options={'disable-javascript':True}, template=template, context=context)
It looks like I'm 3 years late :) I put here a working code sample anyway, as reference for future needs:
urls.py
# here you must import MyPDF from [your-app-name].views
urlpatterns = [
url(r'^pdf/$', MyPDF.as_view(template_name='my_template.html',
filename='my_pdf.pdf'), name='pdf'),
]
views.py
from wkhtmltopdf.views import PDFTemplateView
class MyPDF(PDFTemplateView):
def get_context_data(self, **kwargs):
context = super(MyPDF, self).get_context_data(**kwargs)
context['foo'] = 'BAR'
return context
my_template.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<h1>{{ foo }}</h1>
</body>
</html>
Having the same problem as yours, got everything working with rendering propetly CSS + JS but i'm also unable / don't know how to render or pass the data to get template rendered and then converted.
If someone could give a hint or point in a good direction, it would be awesome.
Related
Update :: Problem solved.just follow the guy below.
in my urls.py
path('', store_view, name='store'),
path('category/<str:category_name>/', category_view, name='category'),
in views.py
def store_view(request):
categories = list(Category.objects.all())
context = {
'categories': categories,
}
return render(request, 'store/store.html', context)
def category_view(request, category_name):
category = Category.objects.get(name=category_name)
context = {
'category': category,
}
return render(request, 'store/single-category-view.html', context)
in my template : store.html , that is rendered by store_view >>
{% for item in categories %}
<a href="{% url 'category' item.name %}">
{{item.name}}
</a>
{% endfor %}
Now,the problem is, in the category column in my DB, i have got one category called 'Laptop/MacBook'.when ever this name is passed to the url, it says >>
"Reverse for 'category' with arguments '('Laptop/MacBook',)' not
found. 1 pattern(s) tried: ['category/(?P<category_name>[^/]+)/$']
But when i changed the category name from Laptop/MacBook to Laptop and MacBook , it worked fine and showed no error.
But i want to keep it as it was,'Laptop/MacBook'.How can i do that??and how do you guys deal with that?
Try encoding and decoding your DB values. Assuming its Python 3:
from urllib.parse import quote, unquote
encoded = quote("Laptop/Macbook", safe="")
decoded = unquote(encoded)
print(encoded, decoded)
Output:
Laptop%2FMacbook Laptop/Macbook
With this your route should take in the right param.
from django.http import HttpResponse, request
from django.shortcuts import render
def store_view(request):
name = "Laptop/Macbook"
return render(request, './store.html', context={"name": name})
def category_view(request, category_name):
print(category_name)
return HttpResponse(b"Here we go!")
templatetags/tags.py
from urllib.parse import quote, unquote
from django import template
register = template.Library()
#register.filter(name='encode')
def encode(name):
return quote(name, safe="")
#register.filter(name='decode')
def decode(name):
return unquote(name)
Template:
{% load tags %}
<a href="{% url 'category' name|encode %}">
{{name}}
</a>
Don't forget to add in settings:
'OPTIONS': {
'libraries':{
'tags': 'templatetags.tags',
}
},
When using a "/", django thinks that you are passing more than one parameter. To fix this, replace str by path in your urls like so:
path('', store_view, name='store'),
path('category/<path:category_name>/', category_view, name='category'),
This will make django understand that the / does not mean there are two separate parameters in your url.
In urls.py file
from articles.views import home
urlpatterns = patterns('',
url(r'^home/$',home.as_view(),name='home'),
)
In views.py file
class home(TemplateView):
template_name='article.html'
def get(self, request):
form = Homeform()
return render(request,self.template_name, {'form':form})
def post(self,request):
file_path = '/u/vinay/checking.py'
args={'file_path':file_path}
return render(request,self.template_name, args)
In article.html file
{% load static %}
<html>
<body>
Download plan</button>
<p>{{ file_path }} </p>
</body>
</html>
But i'm getting no file as output from GUI.
As i'm creating download link for that file in file_path location.So how do i render text from views to article.html
You dont neeed {{}} signs inside template tag. Try this:
"{% static file_path %}"
Check django docs for details.
Please refer to the documentation for template tags:
href="{% static file_path %}"
Ninja'ed..
Also, your view function is all messed up, I'm suprised it displays anything at all:
def vin(request):
return render(request,'article.html', {'file_path':'xyz.py'})
Try this:
class home(TemplateView):
template_name='article.html'
def get_context_data(self,*args,**kwargs):
context = super().get_context_data(*args,**kwargs)
context['file_path'] = '/u/vinay/checking.py'
return context
# END OF VIEW --- no get or post method, let the generic view handle that.
I want to use the url template tag for my generic view.
I have been searching a lot about this and I didn't find what I want, but it seems a simple issue.
I will use the example that the Django book, Making a View Generic, has used:
# urls.py
from django.conf.urls.defaults import *
from mysite import models, views
urlpatterns = patterns('',
(r'^events/$', views.object_list, {'model': models.Event}),
(r'^blog/entries/$', views.object_list, {'model': models.BlogEntry}),
)
# views.py
from django.shortcuts import render
def object_list(request, model):
obj_list = model.objects.all()
template_name = 'mysite/%s_list.html' % model.__name__.lower()
return render(request, template_name, {'object_list': obj_list})
So, I have one view for two URLs, my question is: How can I use the django URL template tag for this two URLs?
I want to do something like this in the html template:
href={% url "mysite.views.object_list" model="Event" %}
href={% url "mysite.views.object_list" model="BlogEntry" %}
Thanks!
You need to define name for the url:
(r'^events/$', views.object_list, {'model': models.Event}, name='my_name'),
and use it instead of the view path:
href={% url "my_name" model="Event" %}
I have a following url pattern:
urlpatterns = pattern('',
...
url(r'edit-offer/(?P<id>\d+)/$', login_required(edit_offer), name='edit_offer'),
)
and a corresponding edit_offer view:
def edit_offer(request, id):
# do stuff here
a link on offer page leads to edit offer view:
<a class="btn" href="{% url edit_offer offer.id %}">Edit</a>
clicking on the button throws a TypeError:
edit_offer() got an unexpected keyword argument 'offer_id'
Any ideas what is going on? I don't see what's wrong here. I have other views with similar patterns and they all work ok.
Try this:
Your urls.py:-
urlpatterns = pattern('whatever_your_app.views',
...
url(r'edit-offer/(?P<id>\d+)/$', 'edit_offer', name='edit_offer'),
)
Your views.py:-
from django.contrib.auth.decorators import login_required
...
#login_required
def edit_offer(request, id):
# do stuff here
and in your template:-
{% url 'edit_offer' offer.id %}
I'm trying to use an example posted on the "github" the link is http://github.com/tstone/django-uploadify. And I'm having trouble getting work. can you help me? I followed step by step, but does not work.
Accessing the "URL" / upload /
the only thing is that returns "True"
part of settings.py
import os
PROJECT_ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
MEDIA_ROOT = os.path.join(PROJECT_ROOT_PATH, 'media')
TEMPLATE_DIRS = ( os.path.join(PROJECT_ROOT_PATH, 'templates'))
urls.py
from django.conf.urls.defaults import *
from django.conf import settings
from teste.uploadify.views import *
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^admin/', include(admin.site.urls)),
url(r'upload/$', upload, name='uploadify_upload'),
)
views.py
from django.http import HttpResponse
import django.dispatch
upload_received = django.dispatch.Signal(providing_args=['data'])
def upload(request, *args, **kwargs):
if request.method == 'POST':
if request.FILES:
upload_received.send(sender='uploadify', data=request.FILES['Filedata'])
return HttpResponse('True')
models.py
from django.db import models
def upload_received_handler(sender, data, **kwargs):
if file:
new_media = Media.objects.create(
file = data,
new_upload = True,
)
new_media.save()
upload_received.connect(upload_received_handler, dispatch_uid='uploadify.media.upload_received')
class Media(models.Model):
file = models.FileField(upload_to='images/upload/', null=True, blank=True)
new_upload = models.BooleanField()
uploadify_tags.py
from django import template
from teste import settings
register = template.Library()
#register.inclusion_tag('uploadify/multi_file_upload.html', takes_context=True)
def multi_file_upload(context, upload_complete_url):
"""
* filesUploaded - The total number of files uploaded
* errors - The total number of errors while uploading
* allBytesLoaded - The total number of bytes uploaded
* speed - The average speed of all uploaded files
"""
return {
'upload_complete_url' : upload_complete_url,
'uploadify_path' : settings.UPLOADIFY_PATH, # checar essa linha
'upload_path' : settings.UPLOADIFY_UPLOAD_PATH,
}
template - uploadify/multi_file_upload.html
{% load uploadify_tags }{ multi_file_upload '/media/images/upload/' %}
<script type="text/javascript" src="{{ MEDIA_URL }}js/swfobject.js"></script>
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery.uploadify.js"></script>
<div id="uploadify" class="multi-file-upload"><input id="fileInput" name="fileInput" type="file" /></div>
<script type="text/javascript">// <![CDATA[
$(document).ready(function() {
$('#fileInput').uploadify({
'uploader' : '/media/swf/uploadify.swf',
'script' : '{% url uploadify_upload %}',
'cancelImg' : '/media/images/uploadify-remove.png/',
'auto' : true,
'folder' : '/media/images/upload/',
'multi' : true,
'onAllComplete' : allComplete
});
});
function allComplete(event, data) {
$('#uploadify').load('{{ upload_complete_url }}', {
'filesUploaded' : data.filesUploaded,
'errorCount' : data.errors,
'allBytesLoaded' : data.allBytesLoaded,
'speed' : data.speed
});
// raise custom event
$('#uploadify') .trigger('allUploadsComplete', data);
}
// ]]</script>
But that's exactly what you've told it to do - if you're not POSTing, then the /upload/ view will simply return True.
I would imagine you want to return an actual rendered template, presumably containing the {% multi_file_upload %} tag.
You may find the following site useful:
https://github.com/tstone/django-uploadify/wiki
line 1 on your template, your tags aren't properly closed/open
should be
{% load uploadify_tags %}{% multi_file_upload '/myphotos/my-photos/'%}
with that said, i am getting all sorts of errors my self... mainly with the csrf verification. i see that tstone is exempting csrf but it still thinks it should be there... and it isn't. so according to django's docs https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/#ajax i added the stuff to make it so csrf should be working. but now i get a 405 because it is trying to post to its self. i'll keep digging and hopefully find a solution.