diff --git a/freekake_api/character/models.py b/freekake_api/character/models.py index 01e3154..582afab 100644 --- a/freekake_api/character/models.py +++ b/freekake_api/character/models.py @@ -1,5 +1,24 @@ from django.db import models +from django.core.exceptions import ValidationError from django_softdelete.models import SoftDeleteModel +from PIL import Image + +def validate_image_size(image): + if image.size > 1 * 1024 * 1024: + raise ValidationError("File size exceeds 1MB.") + +def validate_image_ext(image): + allowed_extensions = ['png', 'jpg', 'jpeg'] + ext = image.name.split('.')[-1].lower() + if ext not in allowed_extensions: + raise ValidationError("Invalid file type. Only PNG or JPEG allowed.") + +def validate_image(image): + try: + img = Image.open(image) + img.verify() + except Exception: + raise ValidationError("Invalid image file.") class Character(SoftDeleteModel): @@ -13,8 +32,16 @@ class Character(SoftDeleteModel): sex = models.BooleanField(blank=False, null=False) type = models.CharField(max_length=25, choices=CHARACTER_TYPE_CHOICES) - featured_image = models.CharField(max_length=1000) - featured_icon = models.CharField(max_length=1000) + featured_image = models.ImageField( + max_length=255, + upload_to="uploads/characters/", + validators=[validate_image_size, validate_image_ext, validate_image], + null=False, blank=False) + featured_icon = models.ImageField( + max_length=255, + upload_to="uploads/characters/", + validators=[validate_image_size, validate_image_ext, validate_image], + null=False, blank=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -28,8 +55,16 @@ class CharacterSkin(models.Model): name = models.CharField(max_length=100) description = models.TextField(blank=True, null=True) - featured_image = models.CharField(max_length=1000) - featured_icon = models.CharField(max_length=1000) + featured_image = models.ImageField( + max_length=255, + upload_to="uploads/character-skins/", + validators=[validate_image_size, validate_image_ext, validate_image], + null=False, blank=False) + featured_icon = models.ImageField( + max_length=255, + upload_to="uploads/character-skins/", + validators=[validate_image_size, validate_image_ext, validate_image], + null=False, blank=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) @@ -45,7 +80,11 @@ class CharacterFragment(models.Model): fragment_number = models.PositiveSmallIntegerField() - featured_icon = models.CharField(max_length=1000) + featured_icon = models.ImageField( + max_length=255, + upload_to="uploads/character-fragments/", + validators=[validate_image_size, validate_image_ext, validate_image], + null=False, blank=False) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) diff --git a/freekake_api/character/serializers.py b/freekake_api/character/serializers.py index b95761c..c3ee684 100644 --- a/freekake_api/character/serializers.py +++ b/freekake_api/character/serializers.py @@ -1,30 +1,42 @@ +from django.forms import ImageField from rest_framework import serializers from character import models class CharacterSerializer(serializers.ModelSerializer): + featured_image = ImageField(max_length=255, allow_empty_file=False) + featured_icon = ImageField(max_length=255, allow_empty_file=False) + class Meta: model = models.Character fields = ['id', 'name', 'description', 'sex', 'type', 'featured_image', 'featured_icon'] class CharacterSkinSerializer(serializers.ModelSerializer): + featured_image = ImageField(max_length=255, allow_empty_file=False) + featured_icon = ImageField(max_length=255, allow_empty_file=False) + class Meta: model = models.CharacterSkin fields = ['id', 'name', 'description', 'featured_image', 'featured_icon', 'character'] class CharacterSkinDetailSerializer(serializers.ModelSerializer): character = CharacterSerializer(read_only=True) + featured_image = ImageField(max_length=255, allow_empty_file=False) + featured_icon = ImageField(max_length=255, allow_empty_file=False) class Meta: model = models.CharacterSkin fields = ['id', 'name', 'description', 'featured_image', 'featured_icon', 'character'] class CharacterFragmentSerializer(serializers.ModelSerializer): + featured_image = ImageField(max_length=255, allow_empty_file=False) + class Meta: model = models.CharacterFragment fields = ['id', 'name', 'description', 'fragment_number', 'featured_icon', 'skin'] class CharacterFragmentDetailSerializer(serializers.ModelSerializer): skin = CharacterSkinSerializer(read_only=True) + featured_image = ImageField(max_length=255, allow_empty_file=False) class Meta: model = models.CharacterFragment