Как реализовать ограничения на загрузку медиафайлов и использовать модели в Django API для крупной системы управления файлами недвижимости?
Я создаю крупную систему управления файлами недвижимости, используя Django API. Я создал отдельное приложение для обработки мультимедиа, и в моей модели я хочу ввести следующие ограничения:
Одно показанное изображение Галерея, содержащая не более 10 изображений Не более 2 загруженных видео, каждое с изображением обложки Не более 2 музыкальных файлов Не более 2 PDF-файлов Для этого я использовал сквозную модель для подключения медиамодели к основной модели, такой как модель "листинг" или "проект".
Мой вопрос заключается в следующем: Должны ли эти ограничения на загрузку обрабатываться в сериализаторе Django или есть лучший подход? Является ли это лучшим способом подключения моделей, особенно когда основные модели могут иметь несколько внешних ключей? Я беспокоюсь о производительности и масштабируемости.
Поскольку скорость имеет решающее значение, а мне нужно подключать мультимедиа к моделям в нескольких приложениях, каков был бы наиболее эффективный способ реализации этих ограничений?
Заранее спасибо!
мой код :
Model.py
from django.db import models
from django.core.validators import FileExtensionValidator
import os
from django.utils.translation import gettext_lazy as _
import uuid
from django.core.exceptions import ValidationError
from src.core.models.base import BaseModel
def upload_media_path(instance, filename):
ext = filename.split('.')[-1].lower()
return f"{instance.content_type.model}/{instance.media_type}/{uuid.uuid4()}.{ext}"
ALLOWED_EXTENSIONS = {
"image": ["jpg", "webp", "png", "svg",],
"video": ["mp4",],
"pdf": ["pdf"],
"audio": ["mp3",],
}
class Media(BaseModel):
MEDIA_TYPE_CHOICES = [
('image', _('Image')),
('video', _('Video')),
('pdf', _('PDF')),
('audio', _('Audio')),
]
media_type = models.CharField(choices=MEDIA_TYPE_CHOICES,
max_length=10,
verbose_name=_("Media Type"), help_text=_("Alternative text for the image for accessibility and SEO purposes.")
)
file = models.FileField(upload_to=upload_media_path,
validators=[
FileExtensionValidator(allowed_extensions=sum(ALLOWED_EXTENSIONS.values(), []))
],
verbose_name=_("File"), help_text=_("Alternative text for the image for accessibility and SEO purposes.")
)
thumbnail = models.ImageField(upload_to='thumbnail_images/',
null=True, blank=True,
verbose_name=_("Thumbnail"), help_text=_("تصویر شاخص برای مدیا")
)
video_cover = models.ImageField(upload_to='video_cover/',
null=True, blank=True,
verbose_name=_("Video Cover"), help_text=_("تصویر کاور برای ویدئو (در صورت نیاز)")
)
title = models.CharField(
max_length=100, null=True, blank=True,
verbose_name=_("Title")
)
alt_text = models.CharField(
max_length=255, blank=True,
verbose_name=_("ALT Text"), help_text=_("Alternative text for the image for accessibility and SEO purposes.")
)
def clean(self):
if self.file and self.file.size > 10 * 1024 * 1024:
raise ValidationError(_("حجم فایل نباید بیشتر از 10 مگابایت باشد!"))
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
def delete(self, *args, **kwargs):
if self.file:
file_path = self.file.path
if os.path.isfile(file_path):
os.remove(file_path)
super().delete(*args, **kwargs)
class Meta:
db_table = 'media'
indexes = [
models.Index(fields=['media_type']),
models.Index(fields=['thumbnail']),
]
verbose_name = _("Media")
verbose_name_plural = _("Media")
Портфолио Media.py
from django.core.exceptions import ValidationError
from django.db import models
from django.utils.translation import gettext_lazy as _
from src.core.models.base import BaseModel
from src.media.models.media import Media
from src.portfolio.models.portfolio import Portfolio
class PortfolioMedia(BaseModel):
portfolio = models.ForeignKey(Portfolio, on_delete=models.CASCADE,
related_name='portfolio_medias',
verbose_name = _("Portfolio"),
help_text = _("The portfolio to which this media belongs.")
)
media = models.ForeignKey(Media, on_delete=models.CASCADE,
related_name='portfolio_links',
verbose_name = _("Media"),
help_text = _("The media file associated with the portfolio.")
)
order = models.PositiveIntegerField(
default=0,
verbose_name=_("Order"),
help_text=_("The order of this media item in the portfolio.")
)
def clean(self):
if self.is_featured and self.media.media_type == 'image':
featured_count = (PortfolioMedia.objects.filter(portfolio=self.portfolio,is_featured=True,media__media_type='image')
.exclude(id=self.id).count())
if featured_count >= 1:
raise ValidationError(_("Only one featured image is allowed per portfolio."))
if self.media.media_type == 'video':
video_count = (PortfolioMedia.objects.filter(portfolio=self.portfolio,media__media_type='video')
.exclude(id=self.id).count())
if video_count >= 3:
raise ValidationError(_("A maximum of 3 videos are allowed per portfolio."))
if not getattr(self.media, 'cover_image', None):
raise ValidationError(_("Each video must have an associated cover image."))
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
class Meta:
ordering = ['order']
db_table = 'portfolio_media'
verbose_name = _("Portfolio Media")
verbose_name_plural = _("Portfolio Media")
indexes = [
models.Index(fields=['portfolio']),
models.Index(fields=['media']),
models.Index(fields=['order']),
]
def __str__(self):
return f"{self.portfolio} - {self.media}"
Please tell me the best solution