2015-12-05 1 views
3

A screenshot (portrait view) моей IDE и Traceback с указанием всего кода, вставленного здесь, может быть проще читать, если у вас есть вертикальный монитор.Попытка понять исходный код Django и причину отсутствия аргумента TypeError

Контекст: попытка сохранить изображение с URL-адреса Django ImageField, размещенного на EC2, с файлами на S3 с использованием S3BotoStorage. Я смущен, потому что все это говорит о том, что Django все еще рассматривает его как локальное хранилище, тогда как S3.

Линии вопроса, которые, кажется, вызывает ошибку:

def get_filename(self, filename): 
    return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename))) 

def get_valid_name(self, name): 
    """ 
    Returns a filename, based on the provided filename, that's suitable for 
    use in the target storage system. 
    """ 
    return get_valid_filename(name) 

TypeError Исключение: get_valid_name() missing 1 required positional argument: 'name'

Последний Local вары TRACBACK перед ошибкой в ​​get_valid_name:

filename  'testimagefilename' 
self  <django.db.models.fields.files.ImageField: image> 

(Только материал внутри этих двух горизонтальных делений ЭКР от меня, все остальное от Django 1.9)

image.image.save('testimagefilename', File(temp), save=True) 

Локальные переменные из TraceBack в этой точке (не уверен насчет ValueError на image, я думаю, это потому, что он не был создан):

File  <class 'django.core.files.base.File'> 
image  Error in formatting: ValueError: The 'image' attribute has no file associated with it. 
requests  <module 'requests' from '/usr/local/lib/python3.4/site-packages/requests/__init__.py'> 
Image  <class 'mcmaster.models.Image'> 
NamedTemporaryFile  <function NamedTemporaryFile at 0x7fb0e1bb0510> 
temp  <tempfile._TemporaryFileWrapper object at 0x7fb0dd241ef0> 

Соответствующие фрагменты исходного кода Django:

files.py

def save(self, name, content, save=True): 
    name = self.field.generate_filename(self.instance, name) 

    if func_supports_parameter(self.storage.save, 'max_length'): 
     self.name = self.storage.save(name, content, max_length=self.field.max_length) 
    else: 
     warnings.warn(
      'Backwards compatibility for storage backends without ' 
      'support for the `max_length` argument in ' 
      'Storage.save() will be removed in Django 1.10.', 
      RemovedInDjango110Warning, stacklevel=2 
     ) 
     self.name = self.storage.save(name, content) 

    setattr(self.instance, self.field.name, self.name) 

    # Update the filesize cache 
    self._size = content.size 
    self._committed = True 

    # Save the object because it has changed, unless save is False 
    if save: 
     self.instance.save() 
save.alters_data = True 

def get_directory_name(self): 
    return os.path.normpath(force_text(datetime.datetime.now().strftime(force_str(self.upload_to)))) 

def get_filename(self, filename): 
    return os.path.normpath(self.storage.get_valid_name(os.path.basename(filename))) 

def generate_filename(self, instance, filename): 
    # If upload_to is a callable, make sure that the path it returns is 
    # passed through get_valid_name() of the underlying storage. 
    if callable(self.upload_to): 
     directory_name, filename = os.path.split(self.upload_to(instance, filename)) 
     filename = self.storage.get_valid_name(filename) 
     return os.path.normpath(os.path.join(directory_name, filename)) 

    return os.path.join(self.get_directory_name(), self.get_filename(filename)) 

storage.py

def get_valid_name(self, name): 
    """ 
    Returns a filename, based on the provided filename, that's suitable for 
    use in the target storage system. 
    """ 
    return get_valid_filename(name) 

text.py

def get_valid_filename(s): 
    """ 
    Returns the given string converted to a string that can be used for a clean 
    filename. Specifically, leading and trailing spaces are removed; other 
    spaces are converted to underscores; and anything that is not a unicode 
    alphanumeric, dash, underscore, or dot, is removed. 
    >>> get_valid_filename("john's portrait in 2004.jpg") 
    'johns_portrait_in_2004.jpg' 
    """ 
    s = force_text(s).strip().replace(' ', '_') 
    return re.sub(r'(?u)[^-\w.]', '', s) 
get_valid_filename = allow_lazy(get_valid_filename, six.text_type) 
+0

Вы, скорее всего, вызывая get_valid_name() из classobject или статически. Каким типом объекта является хранилище? Где вы его создаете? –

ответ

4

Я бы сделать предположение вы не экземпляра класса Storage. Как вы устанавливаете Django для использования пользовательского хранилища? Если вы сделаете это в models.py

image = models.ImageField(storage=MyStorage)

Это не получится именно так, как вы описываете. Он должен быть

image = models.ImageField(storage=MyStorage())