LINUX.ORG.RU

FileField в Django 1.6.2 и UnicodeDecodeError

 , ,


0

2

Django 1.6.2 FileField. Загружаю на сайт через админку текстовые файлы без проблем, при попытке загрузить любые бинарные файлы (в данном случае /usr/share/images/desktop-base/spacefun-grub.png)получаю UnicodeDecodeError:

Exception Type: 	UnicodeDecodeError
Exception Value: 	

'utf-8' codec can't decode byte 0x89 in position 1467: invalid start byte

Exception Location: 	/home/$user/local/lib/python3.4/codecs.py in decode, line 313 
(result, consumed) = self._buffer_decode(data, self.errors, final)

Unicode error hint

The string that could not be encoded/decoded was: g �PNG
Я не понимаю, зачем Django декодирует загружаемый файл в utf перед тем, как записать на сервер? Как это обойти?

Попробовал вставить перед 313 строкой в codecs.py это: data = data.decode(errors='ignore').encode() - так файл загружается, но, понятное дело, файл получается битый

спасибо

Параллельно работает сайт на Python2.7 и Django1.4, никаких проблем нет

alexkarta ()

А у тебя в модели, в методе unicode, используется поле FileField?


myfield = models.FileField(...)

def __unicode__(self):
    return u"%s..." % self.myfield
djnoob ()
Ответ на: комментарий от pi11
Environment:


Request Method: POST
Request URL: http://project.username.ru/admin/main/leak/3/

Django Version: 1.6.2
Python Version: 3.4.0
Installed Applications:
('django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.gis',
 'main')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware')


Traceback:
File "/home/username/local/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  107.                     response = middleware_method(request, callback, callback_args, callback_kwargs)
File "/home/username/local/lib/python3.4/site-packages/django/middleware/csrf.py" in process_view
  170.                 request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
File "/home/username/local/lib/python3.4/site-packages/django/core/handlers/wsgi.py" in _get_post
  151.             self._load_post_and_files()
File "/home/username/local/lib/python3.4/site-packages/django/http/request.py" in _load_post_and_files
  219.                 self._post, self._files = self.parse_file_upload(self.META, data)
File "/home/username/local/lib/python3.4/site-packages/django/http/request.py" in parse_file_upload
  184.         return parser.parse()
File "/home/username/local/lib/python3.4/site-packages/django/http/multipartparser.py" in parse
  140.             for item_type, meta_data, field_stream in Parser(stream, self._boundary):
File "/home/username/local/lib/python3.4/site-packages/django/http/multipartparser.py" in __iter__
  598.         for sub_stream in boundarystream:
File "/home/username/local/lib/python3.4/site-packages/django/http/multipartparser.py" in __next__
  415.             return LazyStream(BoundaryIter(self._stream, self._boundary))
File "/home/username/local/lib/python3.4/site-packages/django/http/multipartparser.py" in __init__
  441.         unused_char = self._stream.read(1)
File "/home/username/local/lib/python3.4/site-packages/django/http/multipartparser.py" in read
  315.         out = b''.join(parts())
File "/home/username/local/lib/python3.4/site-packages/django/http/multipartparser.py" in parts
  308.                 chunk = next(self)
File "/home/username/local/lib/python3.4/site-packages/django/http/multipartparser.py" in __next__
  330.             output = next(self._producer)
File "/home/username/local/lib/python3.4/site-packages/django/http/multipartparser.py" in __next__
  391.             data = self.flo.read(self.chunk_size)
File "/home/username/local/lib/python3.4/site-packages/django/http/request.py" in read
  246.             return self._stream.read(*args, **kwargs)
File "/home/username/local/lib/python3.4/site-packages/django/core/handlers/wsgi.py" in read
  52.             akt_selfread=self._read_limited(size - len(self.buffer))
File "/home/username/local/lib/python3.4/site-packages/django/core/handlers/wsgi.py" in _read_limited
  39.         result = self.stream.read(size)
File "/home/username/local/lib/python3.4/codecs.py" in decode
  314.         (result, consumed) = self._buffer_decode(data, self.errors, final)

Exception Type: UnicodeDecodeError at /admin/main/leak/3/
Exception Value: 'utf-8' codec can't decode byte 0x89 in position 1467: invalid start byte
alexkarta ()

Сами файлы в ФС хранишь или в базе?

Покажи еще определение этого поля в моделях и admin.py для этой модели.

pi11 ★★★★★ ()
Ответ на: комментарий от pi11

models.py


from django.db import models                                                                  
from django.contrib.gis.db import models                                                      
import datetime                                                                               
                                                                                              
class Priority(models.Model):                                                                 
    name=models.CharField(max_length=10)                                                      
    def __str__(self):                                                                        
       return self.name                                                                       
                                                                                              
class Leak(models.Model):                                                                     
    pnt=models.PointField()                                                                   
    objects = models.GeoManager()                                                             
#    openingTime=models.DateTimeField(editable=False)                                         
    openingTime=models.DateTimeField(default=datetime.datetime.today())                       
    closingTime=models.DateTimeField(blank=True,null=True)                                    
    description=models.TextField(blank=True,null=True)                                        
    priority=models.ForeignKey(Priority)                                                      
    picture=models.FileField(upload_to='images/',blank=True,null=True)                        
                                                                                              
    def __str__(self):                                                                        
       return '{0}:{1}'.format(self.id,self.priority.name) 

  
admin.py
from django.contrib.gis import admin
from project.main.models import *


class LeaksAdmin(admin.OSMGeoAdmin):
    default_zoom=17
    openlayers_url = "http://username.ru/static/OpenLayers-2.11/OpenLayers.js"
admin.site.register(Leak, LeaksAdmin)
admin.site.register(Priority)

alexkarta ()
Ответ на: комментарий от alexkarta

openingTime=models.DateTimeField(default=datetime.datetime.today())

Вот так не надо делать, т.к. datetime.datetime.today() - один раз выполнится во время запуска проекта и будет одно и тоже время всегда ставить. вместо этого - auto_now_add=True

pi11 ★★★★★ ()
Ответ на: комментарий от pi11

Судя по всему, проблема в этом

https://groups.google.com/forum/#!msg/django-oscar/yjbK8FSUhqM/os80qcscXGwJ

Python 3 открывает файл в текстовом режима, вместо бинарного, ищу, где бы поменять save(filename, File(open(filepath)) на save(filename, File(open(filepath, 'rb')), save=False)

alexkarta ()
Ответ на: комментарий от pi11

Да, наверное, я рановато решил переезжать, кто знает, что там еще вылезет

alexkarta ()
Ответ на: комментарий от alexkarta

Видимо django все еще не готов для 3-го питона

pi11 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.