photo26/photologue/forms.py
2025-11-28 20:46:18 +01:00

153 lines
5 KiB
Python

# This file is part of photo21
# Copyright (C) 2022 Amicale des élèves de l'ENS Paris-Saclay
# SPDX-License-Identifier: GPL-3.0-or-later
import datetime
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Div, Layout, Submit
from django import forms
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from .models import Gallery, Tag
class MultipleFileInput(forms.ClearableFileInput):
allow_multiple_selected = True
class MultipleFileField(forms.FileField):
allowed_extensions = ['jpg', 'jpeg', 'png', 'gif', 'tiff'] # Specify allowed extensions here
def __init__(self, *args, **kwargs):
kwargs.setdefault(
"widget",
MultipleFileInput(
attrs={
"accept": "image/*",
"class": "mb-3",
}
),
)
super().__init__(*args, **kwargs)
def clean(self, data, initial=None):
single_file_clean = super().clean
if isinstance(data, (list, tuple)):
result = [self.validate_file(d, single_file_clean, initial) for d in data]
else:
result = self.validate_file(data, single_file_clean, initial)
return result
def validate_file(self, file, single_file_clean, initial):
# Perform the default clean
cleaned_file = single_file_clean(file, initial)
# Check the file extension
extension = file.name.split('.')[-1].lower()
if extension not in self.allowed_extensions:
raise forms.ValidationError(
f"{file.name} has an invalid file extension. "
f"Allowed extensions are: {', '.join(self.allowed_extensions)}"
)
return cleaned_file
class UploadForm(forms.Form):
file_field = MultipleFileField(label="")
gallery = forms.ModelChoiceField(
Gallery.objects.all(),
label=_("Gallery"),
required=False,
empty_label=_("-- Create a new gallery --"),
help_text=_(
"Select a gallery to add these images to. Leave this empty to "
"create a new gallery from the supplied title."
),
)
new_gallery_title = forms.CharField(
label=_("New gallery title"),
max_length=250,
required=False,
)
new_gallery_date_start = forms.DateField(
label=_("New gallery event start date"),
initial=datetime.date.today,
required=False,
)
new_gallery_date_end = forms.DateField(
label=_("New gallery event end date"),
initial=datetime.date.today,
required=False,
)
new_gallery_description = forms.CharField(
label=_("Description"),
required=False
)
new_gallery_tags = forms.ModelMultipleChoiceField(
Tag.objects.all(),
label=_("New gallery tags"),
required=False,
help_text=_(
'Hold down "Control", or "Command" on a Mac, to select more than one.'
),
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.use_custom_control = False
self.helper.layout = Layout(
"file_field",
"gallery",
"new_gallery_title",
Div(
Div("new_gallery_date_start", css_class="col"),
Div("new_gallery_date_end", css_class="col"),
css_class="row",
),
"new_gallery_description",
"new_gallery_tags",
Submit("submit", _("Upload"), css_class="btn btn-success mt-2"),
)
def clean_new_gallery_title(self):
title = self.cleaned_data["new_gallery_title"]
if title and Gallery.objects.filter(title=title).exists():
raise forms.ValidationError(_("A gallery with that title already exists."))
return title
def clean(self):
cleaned_data = super().clean()
# Check that either an existing gallery is chosen, or new_gallery_title is filled
if not (
bool(cleaned_data["gallery"])
^ bool(cleaned_data.get("new_gallery_title", None))
):
raise forms.ValidationError(
_("Select an existing gallery, or enter a title for a new gallery.")
)
return cleaned_data
def get_or_create_gallery(self):
"""
Get or create gallery
"""
gallery = self.cleaned_data["gallery"]
if not gallery:
# Create new gallery
title = self.cleaned_data.get("new_gallery_title")
gallery = Gallery.objects.create(
title=title,
slug=slugify(title),
date_start=self.cleaned_data["new_gallery_date_start"],
date_end=self.cleaned_data["new_gallery_date_end"],
description=self.cleaned_data["new_gallery_description"]
)
for tag in self.cleaned_data["new_gallery_tags"]:
gallery.tags.add(tag)
return gallery