Функция модели Django для сохранения ImageField, если изображение не указано = execption - PullRequest
0 голосов
/ 31 марта 2019

У меня есть функция Django для правильного сохранения изображения.В настоящее время кажется, что Django-SmartFields в данный момент глючит, см .: https://github.com/lehins/django-smartfields/issues/17 и sorl не работает должным образом, не знаю почему.Итак, я быстро записал это:

models.py

class Post(models.Model):
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(verbose_name="Title", max_length=40)
    content = models.TextField(verbose_name="Content", max_length=5000)
    tag = models.CharField(verbose_name="Tags/Meta - (sep. by comma)", max_length=50, blank=True)
    category = models.ForeignKey(Category, verbose_name="Category", on_delete=models.CASCADE, null=True)
    postattachment = fields.FileField(
        verbose_name="Attachment",
        blank=True,
        null=True,
        upload_to=get_file_path_user_uploads,
        validators=[file_extension_postattachment, file_size_postattachment]
    )
    postcover = fields.ImageField(
        verbose_name="Cover",
        blank=True,
        null=True,
        upload_to=get_file_path_user_uploads,
        validators=[default_image_size, default_image_file_extension]
    )
    up_vote = models.IntegerField(verbose_name='Post Up-Vote(s)', default=0)
    down_vote = models.IntegerField(verbose_name='Post Down-Vote(s)', default=0)
    published_date = models.DateField(auto_now_add=True, null=True)

    def save(self, *args, **kwargs):
        imageTemproary = Image.open(self.postcover)
        outputIoStream = BytesIO()
        imageTemproaryResized = imageTemproary.resize((700, 525))
        imageTemproaryResized.save(outputIoStream, format='JPEG', quality=85)
        outputIoStream.seek(0)
        self.postcover = InMemoryUploadedFile(outputIoStream, 'ImageField',
                                                  "%s.jpeg" % self.postcover.name.split('.')[0], 'image/jpeg',
                                                  sys.getsizeof(outputIoStream), None)
        super(Post, self).save(*args, **kwargs)

Но если я теперь хочу очистить изображение через мою форму, я получаю следующую ошибку:

Атрибут 'postcover' не имеет связанного с ним файла.

full trace:

 Internal Server Error: /post/1/edit/
 Traceback (most recent call last):
   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/exception.py", line 34, in inner
     response = get_response(request)
  File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 126, in _get_response
    response = self.process_exception_by_middleware(e, request)
   File "/usr/local/lib/python3.6/site-packages/django/core/handlers/base.py", line 124, in _get_response
     response = wrapped_callback(request, *callback_args, **callback_kwargs)
   File "/app/app_Accounts/decorators.py", line 33, in _wrapped_view
     return view_func(request, *args, **kwargs)
   File "/usr/local/lib/python3.6/site-packages/ratelimit/decorators.py", line 30, in _wrapped
     return fn(*args, **kw)
   File "/app/app/views.py", line 473, in post_edit
     post.save()
   File "/app/app/models.py", line 173, in save
     imageTemproary = Image.open(self.postcover)
   File "/usr/local/lib/python3.6/site-packages/PIL/Image.py", line 2638, in open
     fp.seek(0)
   File "/usr/local/lib/python3.6/site-packages/django/core/files/utils.py", line 20, in <lambda>
     seek = property(lambda self: self.file.seek)
   File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/files.py", line 41, in _get_file
     self._require_file()
   File "/usr/local/lib/python3.6/site-packages/django/db/models/fields/files.py", line 38, in _require_file
     raise ValueError("The '%s' attribute has no file associated with it." % self.field.name)
ValueError: The 'postcover' attribute has no file associated with it.

Делает кого-л.есть быстрый способ обойти это поведение?

Спасибо заранее

1 Ответ

0 голосов
/ 31 марта 2019

почему вы не можете проверить, существует ли изображение

import os //added
def save(self, *args, **kwargs):
     super(Post, self).save(*args, **kwargs)
     if self.postcover:
         if os.path.exists(self.postcover.path):     //this was added
            imageTemproary = Image.open(self.postcover)
            outputIoStream = BytesIO()
            imageTemproaryResized = imageTemproary.resize((700, 525))
            imageTemproaryResized.save(outputIoStream, format='JPEG', quality=85)
            outputIoStream.seek(0)
            self.postcover = InMemoryUploadedFile(outputIoStream, 'ImageField',
                                                  "%s.jpeg" % self.postcover.name.split('.')[0], 'image/jpeg',
                                                  sys.getsizeof(outputIoStream), None)
     super(Post, self).save(*args, **kwargs)
...