diff --git a/web/forms.py b/web/forms.py index 96489d524..16af84593 100644 --- a/web/forms.py +++ b/web/forms.py @@ -1690,7 +1690,7 @@ class Meta: attrs={ "accept": "image/png,image/jpeg,image/gif", "required": True, - "help_text": "Upload a meme image (JPG, PNG, or GIF, max 2MB)", + "help_text": "Upload a meme image (JPG, PNG, or GIF, max 1MB)", } ), } @@ -1700,11 +1700,16 @@ def __init__(self, *args, **kwargs): self.fields["subject"].required = False self.fields["subject"].help_text = "Select an existing subject" - # Improve error messages - self.fields["image"].error_messages = { - "required": "Please select an image file.", - "invalid": "Please upload a valid image file.", - } + # When editing an existing meme, the image should not be required. + if self.instance and self.instance.pk and "image" in self.fields: + self.fields["image"].required = False + # Image field is excluded from MemeEditForm; this branch exists only for defensive coverage + + if "image" in self.fields: + self.fields["image"].error_messages = { + "required": "Please select an image file.", + "invalid": "Please upload a valid image file.", + } def clean(self): cleaned_data = super().clean() @@ -1716,6 +1721,20 @@ def clean(self): return cleaned_data + def clean_image(self): + image = self.cleaned_data.get("image") + # if editing and no new file provided, don't validate size/contents + if not image: + return image + + if self.instance and self.instance.pk: + raise ValidationError("Uploaded image cannot be replaced after upload.") + + limit_mb = 1 + if image.size > limit_mb * 1024 * 1024: + raise ValidationError(f"Image file is too large. Size should not exceed {limit_mb} MB.") + return image + def save(self, commit=True): meme = super().save(commit=False) @@ -1734,6 +1753,19 @@ def save(self, commit=True): return meme +# Form used during updates, image may not be changed by users +class MemeEditForm(MemeForm): + """Form used during meme updates; uploaded image is immutable.""" + + class Meta(MemeForm.Meta): + fields = tuple(f for f in MemeForm.Meta.fields if f != "image") + + def __init__(self, *args: object, **kwargs: object) -> None: + super().__init__(*args, **kwargs) + # ensure image field is not present + self.fields.pop("image", None) + + class StudentEnrollmentForm(forms.Form): first_name = forms.CharField( max_length=30, required=True, widget=TailwindInput(attrs={"placeholder": "First Name"}), label="First Name" diff --git a/web/migrations/0026_enhance_meme_model.py b/web/migrations/0026_enhance_meme_model.py index c0f3cfc12..1d2a2185b 100644 --- a/web/migrations/0026_enhance_meme_model.py +++ b/web/migrations/0026_enhance_meme_model.py @@ -24,7 +24,7 @@ class Migration(migrations.Migration): ( "image", models.ImageField( - help_text="Upload a meme image (JPG, PNG, or GIF, max 2MB)", + help_text="Upload a meme image (JPG, PNG, or GIF, max 1MB)", upload_to="memes/", validators=[web.models.validate_image_size, web.models.validate_image_extension], ), diff --git a/web/models.py b/web/models.py index 6b8ea8ef4..ac98a780f 100644 --- a/web/models.py +++ b/web/models.py @@ -1765,7 +1765,7 @@ def save(self, *args, **kwargs): def validate_image_size(image): """Validate that the image file is not too large.""" file_size = image.size - limit_mb = 2 + limit_mb = 1 if file_size > limit_mb * 1024 * 1024: raise ValidationError(f"Image file is too large. Size should not exceed {limit_mb} MB.") @@ -1794,7 +1794,7 @@ class Meme(models.Model): image = models.ImageField( upload_to="memes/", validators=[validate_image_size, validate_image_extension], - help_text=_("Upload a meme image (JPG, PNG, or GIF, max 2MB)"), + help_text=_("Upload a meme image (JPG, PNG, or GIF, max 1MB)"), ) uploader = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, related_name="memes", null=True) created_at = models.DateTimeField(auto_now_add=True) diff --git a/web/templates/add_meme.html b/web/templates/add_meme.html index e7c12a71e..d37b078c1 100644 --- a/web/templates/add_meme.html +++ b/web/templates/add_meme.html @@ -1,26 +1,44 @@ {% extends "base.html" %} {% block title %} - Add Educational Meme + {% if is_edit %} + Edit Educational Meme + {% else %} + Add Educational Meme + {% endif %} {% endblock title %} {% block content %}