Мое решение состоит в том, чтобы переопределить метод сохранения модели и проверить, не создается ли модель впервые, а также проверить, не пусто ли поле изображения postImage. Если это так, заполните поле postImage содержимым изображения Radom. Django справится с остальным
Если мы используем путь к изображению Radom непосредственно в нашей модели, мы в конечном итоге будем обслуживать некоторые файлы пост-модели из папки media, а некоторые — из статического каталога, что не рекомендуется. Вместо этого мы передаем содержимое файла изображения в поле 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)
Также нет необходимости устанавливать ‘/media’ в пути upload_to. Django будет читать медиа-путь из переменной настроек
Лучше всего переместить этот набор изображений по умолчанию из статического каталога в другую папку, возможно, в другую папку с ресурсами имен или любым другим значимым именем, поскольку содержимое статического каталога будет часто меняться по мере роста проекта.
person
Iyvin Jose
schedule
28.09.2018