0

I put the ImageField into the Model and can successfully upload the image file. But when try to open the file through admin page. Cannot open the file but there is an error says "500 Internal server error".

In the file name there are some non-ascii letters inside. How can I fix this problem?

class Customer(User):
    profile_image = models.ImageField(upload_to='customers/photos', null=True, blank=True)
    hospital = models.ForeignKey('Hospital', null=True, blank=True)
    treatments = models.ManyToManyField('Treatment', blank=True)
    verified = models.BooleanField(default=False)

    def get_full_name(self):
        return self.email

    def get_short_name(self):
        return self.email


image file name = "데이비드_베컴2.jpg"

actually this model has more then one field..

+) admin.py

class CustomerAdmin(UserAdmin):
    form = CustomerChangeForm
    add_form = CustomerCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('email', 'phonenumber', 'is_admin')
    list_filter = ('is_admin',)
    fieldsets = (
        (None, {'fields': ('email', 'password', 'phonenumber', 'smscheck',
                  'name', 'hospital', 'major', 'treatments', 'info', 'profile_image', 'verified', )}),
        ('Personal info', {'fields': ()}),
        ('Permissions', {'fields': ('is_active', 'is_admin',)}),
    )
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'password1', 'password2', 'phonenumber', 'smscheck',
                  'name', 'hospital', 'major', 'treatments', 'info', 'verified', 'is_active', 'is_admin')}
        ),
    )
    search_fields = ('email', 'phonenumber')
    ordering = ('email',)
    filter_horizontal = ()

also when I put the file encoded with english it has no problem.. for example, "myprofile.jpg"

+) error in detail

Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/wsgiref/handlers.py", line 85, in run
    self.result = application(self.environ, self.start_response)
  File "/usr/local/lib/python2.7/site-packages/django/contrib/staticfiles/handlers.py", line 63, in __call__
    return self.application(environ, start_response)
  File "/usr/local/lib/python2.7/site-packages/whitenoise/base.py", line 57, in __call__
    static_file = self.find_file(environ['PATH_INFO'])
  File "/usr/local/lib/python2.7/site-packages/whitenoise/django.py", line 72, in find_file
    if self.use_finders and url.startswith(self.static_prefix):
UnicodeDecodeError: 'ascii' codec can't decode byte 0xeb in position 22: ordinal not in range(128)

How can I fix this problem? thanks in advance!

nextdoordoc
  • 1,727
  • 6
  • 20
  • 30
  • You'll have to either enable DEBUG mode and see what the actual error is, or you'll have to enable logging and make it send you an email with the error. "500 Internal Server Error" only means that you app returned an error, but there's no way to tell which error is it. – Tiago Jul 12 '16 at 12:45
  • @Tiago thanks for the reply. debug mode is already on and i am trying to use this url of image though django restf framework. It's not easy to see the problem in detail even the debug mode is turned on. – nextdoordoc Jul 12 '16 at 12:49
  • post the full stack trace please – e4c5 Jul 12 '16 at 13:08

2 Answers2

1

Finally I found the solution for this error.

Just implement the new custom field for yourself.

import unicodedata
from django.db.models import ImageField

class MyImageField(ImageField):

    def __init__(self, *args, **kwargs):
        super(MyImageField, self).__init__(*args, **kwargs)

    def clean(self, *args, **kwargs):
        data = super(MyImageField, self).clean(*args, **kwargs)
        data.name = unicodedata.normalize('NFKD', data.name).encode('ascii', 'ignore')
        return data

For more information about this u can check this out here.

nextdoordoc
  • 1,727
  • 6
  • 20
  • 30
0

Make your class is unicode compatible.

from __future__ import unicode_literals
from django.utils.encoding import python_2_unicode_compatible

@python_2_unicode_compatible 
class Customer(User):
    profile_image = models.ImageField(upload_to='customers/photos', null=True, blank=True)

    def __str__(self):
        return self.profile_image.path

    def __unicode__(self):
        return unicode(self.profile_image.path)

also, make sure your media directory is defined in settings.py:

MEDIA_ROOT = './media/'
MEDIA_URL = '/media/'

Make sure your LANG environment variable is set - use your locale

export LANG="en_US.UTF-8"

also add export to ~/.bashrc

dmitryro
  • 3,463
  • 2
  • 20
  • 28
  • See https://docs.djangoproject.com/en/1.9/topics/files/ - you also have **name** and **url** in addition to **path** – dmitryro Jul 12 '16 at 12:53
  • I follow your instruction but the other error come out.. the error is like this. << The 'profile_image' attribute has no file associated with it. >> – nextdoordoc Jul 12 '16 at 13:10
  • So based on the structure above verify you're uploading something into `./media/customers/photos` and there's a file there - it might be that your file is not actually uploaded - if there you can check the created model instance for it's attributes. Looks like a mixture of several issues. – dmitryro Jul 12 '16 at 13:15
  • Show us your `admin.py` - it has to include the `CustomerAdmin` class – dmitryro Jul 12 '16 at 13:17
  • Just a side note - it's a better practice to use OneOnOneField with Django User than explicitly extending it, as it provides cleaner design and simpler model management. – dmitryro Jul 12 '16 at 13:19
  • Also look at https://docs.djangoproject.com/en/dev/ref/unicode/#conversion-functions - you need to provide your filename is UTF-8 compatible – dmitryro Jul 12 '16 at 13:39