我的解决方案是覆盖模型保存方法并检查模型是否是第一次创建并检查 postImage 图像字段是否为空。如果是这样用随机图像的内容填充 postImage 字段。 Django 会处理剩下的事情
如果我们直接在模型中使用随机图像的路径,我们最终会像从媒体文件夹和静态目录中提供一些后期模型文件一样,这是不推荐的。相反,我们将图像文件内容提供给 postImage 字段,Django 会将图像保存到媒体文件夹,因此我们可以从媒体文件夹本身提供所有模型图像。沃拉
代码
以下代码在 Python 3.6 中测试
请将代码添加到您的 models.py
from pathlib import Path
from random import randint
import time
from django.core.files import File
from django.db import models
allowed_image_extensions = ['.jpg', '.png', '.jpeg']
def get_file_extension(file_path):
return Path(file_path).suffix
def get_files_in_directory(directory, absolute_path=False):
from os import listdir
from os.path import isfile
only_files = [f for f in listdir(directory) if isfile("{}/{}".format(directory, f))]
if not absolute_path:
return only_files
else:
return ["{}/{}".format(directory, file_) for file_ in only_files]
def get_random_image_from_directory(directory_path, image_extension=None):
files_in_directory_path = get_files_in_directory(directory_path, absolute_path=True)
if image_extension:
allowed_file_types = [image_extension]
else:
allowed_file_types = allowed_image_extensions
# filter out files of type other than required file types
filtered_files_list = [_file for _file in files_in_directory_path if
get_file_extension(_file).lower() in allowed_file_types]
random_index = randint(0, len(filtered_files_list) - 1)
random_file_path = filtered_files_list[random_index]
random_file_content = File(open(random_file_path, 'rb'))
return random_file_content
def get_post_image_path(instance, filename):
path_first_component = 'posts'
ext = get_file_extension(filename)
current_time_stamp = int(time.time())
file_name = '{}/posts_{}_{}{}'.format(path_first_component, instance.id, current_time_stamp, ext)
full_path = path_first_component + file_name
return full_path
class Post(models.Model):
heading = models.CharField(max_length=150)
author = models.ForeignKey(User)
postBody = models.TextField()
postDate = models.DateTimeField('posting date')
postImage = models.ImageField(blank=True, null=True, upload_to=get_post_image_path)
# override model save method
def save(self, *args, **kwargs):
# check model is new and postImage is empty
if self.pk is None and not self.postImage:
random_image = get_random_image_from_directory(settings.STATIC_ROOT)
self.postImage = random_image
random_image.close()
super(Post, self).save(*args, **kwargs)
也无需在upload_to 路径中设置'/media'。 Django 将从设置变量中读取媒体路径
最佳做法是将这些默认图像集从静态目录移到另一个文件夹,可能是另一个具有名称资源或任何其他有意义名称的文件夹,因为随着项目的增长,静态目录内容会经常更改