Django Rest Framework 可选图像字段不起作用

Django Rest Framework Optional Image field is not working

我正在尝试使图像字段在序列化程序中可选。但它仍然没有使图像字段成为可选的。我的代码如下:

照片上传文件管理class:

class FileManager:
       @staticmethod
       def photo_path(instance, filename):
           basefilename, file_extension = os.path.splitext(filename)
           date = datetime.datetime.today()
           uid = uuid.uuid4()
           if isinstance(instance, User):
               return f'profile_pic/{instance.email}/{uid}-{date}{file_extension}'
           elif isinstance(instance, BlogPost):
              print(file_extension)
              return f'blog_pic/{instance.author.email}/{uid}-{date}{file_extension}'

我的模型class:

class BlogPost(models.Model):
'''
Manage Blog Posts of the user
'''
author = models.ForeignKey(get_user_model(), 
            on_delete=models.DO_NOTHING, 
            related_name='blog_author')

content = models.TextField(max_length=600, blank=True, null=True)
content_image = models.FileField(upload_to= FileManager.photo_path, null=True, blank=True)
is_approved = models.BooleanField(default=False)

updated_on = models.DateTimeField(auto_now_add=True)
timestamp = models.DateTimeField(auto_now_add=True)

def save(self, *args, **kwargs):
    super(BlogPost, self).save(*args, **kwargs)
    img = Image.open(self.content_image.path)
    if img.height > 600 or img.width > 450:
        output_size = (600, 450)
        img.thumbnail(output_size)
        img.save(self.content_image.path)

我的序列化器Class:

class BlogPostUserSerializer(serializers.HyperlinkedModelSerializer):
'''
Will be serializing blog data
'''
author = UserListSerializer(read_only=True)
content = serializers.CharField(required=False)
content_image = serializers.ImageField(required=False, max_length=None, allow_empty_file=True, use_url=True)

class Meta:
    model = BlogPost
    fields = (  
                'url',
                'id', 
                'content', 
                'content_image', 
                'author')

def validate(self, data):
    if not data.get('content') and not data.get('content_image'):
        raise serializers.ValidationError({'message':'No-content or Content image were provided'})
    return data

错误文本:

ValueError at /forum/write-blog

The 'content_image' attribute has no file associated with it.

我已经完成了 Django Rest Framework 的 Doc but no help. Even the 其他人无法正常工作请帮助我被卡住了。

尝试这样做

class BlogPostUserSerializer(serializers.HyperlinkedModelSerializer):
'''
Will be serializing blog data
'''
   author = UserListSerializer(read_only=True)

   class Meta:
       model = BlogPost
       fields = (  
                'url',
                'id', 
                'content', 
                'content_image', 
                'author')

       read_only_fields = ['id',]
   def validate(self, data):
      if data.get('content') is None and data.get('content_image') is None:
          raise serializers.ValidationError({'message':'No-content or Content image were provided'})
      return data

其实我已经解决了这个问题。现在我明白了,它从来都不是来自我的序列化器 Class。

实际上它来自我的模型 class 的保存方法。它试图在保存时修改图像,但由于模型字段为空,因此它会抛出错误。我解决的代码。

class BlogPost(models.Model):
'''
Manage Blog Posts of the user
'''
author = models.ForeignKey(get_user_model(), 
            on_delete=models.DO_NOTHING, 
            related_name='blog_author')

content = models.TextField(max_length=600, blank=True, null=True)
content_image = models.FileField(upload_to= FileManager.photo_path, null=True, blank=True)
is_approved = models.BooleanField(default=False)

updated_on = models.DateTimeField(auto_now_add=True)
timestamp = models.DateTimeField(auto_now_add=True)

def save(self, *args, **kwargs):
    super(BlogPost, self).save(*args, **kwargs)
    if self.content_image:
        img = Image.open(self.content_image.path)
        if img.height > 600 or img.width > 450:
            output_size = (600, 450)
            img.thumbnail(output_size)
            img.save(self.content_image.path)

class Meta:
    unique_together = ( 'author', 
                        'content', 
                        'content_image')

这里我添加了一个条件,如果有图片就修改它。

        if self.content_image:
        img = Image.open(self.content_image.path)