Joseph
Joseph

Reputation: 290

Displaying PDFs in django; decoding error

I'm trying to pass a PDF into a Django app and am running into an issue with unicode/decoding the PDF. The PDFs are being stored in a mysql database, in a mediumblob field. I'd appreciate any help on this, as it seems the encoding is running into a problem with the metadata of the PDF, and I'm not sure where to go with this - I've checked out several questions that seem similar but can't find what I'm looking for. Do I need to decode/recode the PDFs somehow? Thanks!

Here is the error:

Request Method:     POST
Request URL:    http://0.0.0.0:8000/admin/pdf/abc/
Exception Type:     DjangoUnicodeDecodeError
Exception Value:    'utf8' codec can't decode byte 0x89 in position 614: unexpected code byte
Exception Location:     /usr/lib/python2.5/site-packages/django/utils/encoding.py in  force_unicode, line 92
Python Executable:  /usr/bin/python

My code is below:

class ABCAdmin(admin.ModelAdmin):

actions = ['print_selected_pdf']

def get_user(self):
    return '%s'%(self.user.username)

def create_pdf(self, queryset):
    response = HttpResponse(mimetype="applicaton/pdf")
    response['Content-Disposition'] = 'attachment; filename=form.pdf'


    p=canvas.Canvas(response)
    # loop through the objects
    for  obj in queryset:
         string1 = (obj.form)

        # update the label_printed to true
         obj.pdf_printed=True
         obj.save()

    p.save()
    return response

def print_selected_pdf(self, request, queryset):
    # prints the pdfs for those that are selected,
    # regardless if the pdf_printed field is true or false
    return self.create_pdf(queryset.order_by('user'))

print_selected_pdf.short_description = "Print selected PDF"
get_user.short_description='Printed By'

list_display=('form_no',get_user,'request_date','pdf_printed')

def queryset(self,request):
    # get the user id
    user = User.objects.get(username=request.user)

    if request.user.is_superuser:
        qs = self.model._default_manager.all()
    else:
        qs = self.model._default_manager.filter(user=user.id)
    return qs

def formfield_for_foreignkey(self, db_field, request, **kwargs):
    if db_field.name == "user" and not request.user.is_superuser:
        # get the user id
        user = User.objects.get(username=request.user)
        kwargs["queryset"]=User.objects.filter(id=user.id)
        return db_field.formfield(**kwargs)
    return super(ABCAdmin,self).formfield_for_foreignkey(
        db_field, request, **kwargs)

admin.site.register(ABC, ABCAdmin)

Edit: Full trackback:

Environment:

Request Method: POST
Request URL: http://0.0.0.0:8000/admin/pdf/abc/
Django Version: 1.1
Python Version: 2.5.2
Installed Applications:
['django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.admin',
 'app.pdf']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware')


Traceback:
File "/usr/lib/python2.5/site-packages/django/core/handlers/base.py" in get_response
  92.                 response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.5/site-packages/django/contrib/admin/options.py" in wrapper
  226.                 return self.admin_site.admin_view(view)(*args, **kwargs)
File "/usr/lib/python2.5/site-packages/django/views/decorators/cache.py" in    _wrapped_view_func
  44.         response = view_func(request, *args, **kwargs)
File "/usr/lib/python2.5/site-packages/django/contrib/admin/sites.py" in inner
  186.             return view(request, *args, **kwargs)
File "/usr/lib/python2.5/site-packages/django/contrib/admin/options.py" in   changelist_view
  912.             response = self.response_action(request,queryset=cl.get_query_set())
File "/usr/lib/python2.5/site-packages/django/contrib/admin/options.py" in  response_action
  694.             response = func(self, request, queryset.filter(pk__in=selected))
File ".../pdf/admin.py" in print_selected_pdf
  56.         return self.create_pdf(queryset.order_by('user'))
File ".../pdf/admin.py" in create_pdf
  48.              obj.save()
File "/usr/lib/python2.5/site-packages/django/db/models/base.py" in save
  410.         self.save_base(force_insert=force_insert, force_update=force_update)
File "/usr/lib/python2.5/site-packages/django/db/models/base.py" in save_base
  474.                         rows = manager.filter(pk=pk_val)._update(values)
File "/usr/lib/python2.5/site-packages/django/db/models/query.py" in _update
  444.         return query.execute_sql(None)
File "/usr/lib/python2.5/site-packages/django/db/models/sql/subqueries.py" in execute_sql
  120.         cursor = super(UpdateQuery, self).execute_sql(result_type)
File "/usr/lib/python2.5/site-packages/django/db/models/sql/query.py" in execute_sql
  2369.         cursor.execute(sql, params)
File "/usr/lib/python2.5/site-packages/django/db/backends/util.py" in execute
  22.             sql = self.db.ops.last_executed_query(self.cursor, sql, params)
File "/usr/lib/python2.5/site-packages/django/db/backends/__init__.py" in last_executed_query
  213.             u_params = tuple([to_unicode(val) for val in params])
File "/usr/lib/python2.5/site-packages/django/db/backends/__init__.py" in <lambda>
  211.         to_unicode = lambda s: force_unicode(s, strings_only=True)
File "/usr/lib/python2.5/site-packages/django/utils/encoding.py" in force_unicode
  92.         raise DjangoUnicodeDecodeError(s, *e.args)

Exception Type: DjangoUnicodeDecodeError at /admin/pdf/abc/ Exception Value: 'utf8' codec can't decode byte 0x89 in position 614: unexpected code byte. You passed in [redacted for length - here it displayed all of the metadata in the PDF]

Upvotes: 0

Views: 479

Answers (2)

Joseph
Joseph

Reputation: 290

I had to use a queryset to avoid the decoding error. Filefield is not practical in my situation.

Upvotes: 0

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798566

The PDFs are being stored in a mysql database, in a mediumblob field.

You just lost the game. Use a FileField instead.

Upvotes: 4

Related Questions