Reputation: 1343
I am trying to render html to pdf and include it as a django action, however, for some odd reason, I seem to keep getting the issue that the object has no attribute 'some_attribute'.
My view looks like this:
class CreatePdf(ContextMixin, View):
def get_context_data(self, obj, request):
cxt = {'some_attribute': obj.some_attribute,
'today': date.today()}
return cxt
def create_pdf(self, some_template, some_dict={}):
template = get_template(some_template)
html = template.render(some_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("ISO-8859-1")), result)
if not pdf.err:
return HttpResponse(result.getvalue())
return None
And the action, which had the purpose to call everything and do all the magic, looks like this:
def get_pdf(self, obj, request):
pdf_view = views.CreatePdf()
pdf = pdf_view.create_pdf('templates/some_template.html', pdf_view.get_context_data(obj,request))
return HttpResponse(pdf)
I thought, that using get_context_data
will get the fields of the selected object in the admin field, however, it seems to through me the same error.
Last, but not least, in my admin.py
I have:
class MyAdmin(admin.ModelAdmin):
actions = [get_pdf]
Upvotes: 0
Views: 1025
Reputation: 600059
There are several errors here.
The main one is that the signature of a ModelAdmin action method is not self, obj, request
but self, request, queryset
. So you are passing the request in the wrong position, which explains why Django is saying that it is the request that lacks the error.
Note also that the final parameter is a queryset, not an object. This is because an admin action is called on all the items that have the checkbox selected. So, you need to iterate through the queryset and do something with each item. I'm not sure how you will want that to work when your action is creating querysets; it may well be that actions are not what you want here.
Currently, CreatePdf is not actually a view, so I don't know why you are inheriting from view classes; it would work just as well inheriting directly from object. However, the alternative is to make it an actual view, registered via the get_urls()
method.
Upvotes: 1