photo26/photologue/forms.py
krek0 15414d4d4d
All checks were successful
Docker / build (release) Successful in 9s
Allow staff to upload photos has another user.
2026-05-16 18:46:51 +02:00

170 lines
5.6 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.contrib.auth import get_user_model
from django.utils.text import slugify
from django.utils.translation import gettext_lazy as _
from django_select2.forms import ModelSelect2MultipleWidget, ModelSelect2Widget
from .models import Gallery, Tag
User = get_user_model()
class MultipleFileInput(forms.ClearableFileInput):
allow_multiple_selected = True
class MultipleFileField(forms.FileField):
def __init__(self, *args, **kwargs):
kwargs.setdefault(
"widget",
MultipleFileInput(
attrs={
"accept": "image/*,video/*",
"class": "mb-3",
}
),
)
super().__init__(*args, **kwargs)
def clean(self, data, initial=None):
single_file_clean = super().clean
if isinstance(data, (list, tuple)):
return [single_file_clean(d, initial) for d in data]
return single_file_clean(data, initial)
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,
widget=forms.DateInput(attrs={"type":"date"})
)
new_gallery_date_end = forms.DateField(
label=_("New gallery event end date"),
initial=datetime.date.today,
required=False,
widget=forms.DateInput(attrs={"type":"date"})
)
new_gallery_description = forms.CharField(
widget=forms.Textarea(attrs={"rows": 4}),
label=_("Description"),
required=False,
)
new_gallery_tags = forms.ModelMultipleChoiceField(
Tag.objects.all(),
label=_("New gallery tags"),
required=False,
widget=ModelSelect2MultipleWidget(
model=Tag,
search_fields=['name__icontains'],
attrs = {
'data-minimum-input-length': 0,
'data-placeholder': 'Select tags',
}
)
)
def __init__(self, *args, **kwargs):
is_staff = kwargs.pop("is_staff", False)
super().__init__(*args, **kwargs)
if is_staff:
self.fields["owner"] = forms.ModelChoiceField(
User.objects.all(),
label=_("Upload as"),
required=False,
empty_label=_("-- Myself --"),
widget=ModelSelect2Widget(
model=User,
search_fields=["username__icontains", "first_name__icontains", "last_name__icontains"],
attrs={
"data-minimum-input-length": 0,
"data-placeholder": "-- Myself --",
},
),
)
self.helper = FormHelper()
self.helper.include_media = False
self.helper.use_custom_control = False
layout_fields = [
"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",
]
if is_staff:
layout_fields.append("owner")
layout_fields.append(Submit("submit", _("Upload"), css_class="btn btn-success mt-2"))
self.helper.layout = Layout(*layout_fields)
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_owner(self, fallback):
return self.cleaned_data.get("owner") or fallback
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")
base_slug = slugify(title)
slug = base_slug
counter = 2
while Gallery.objects.filter(slug=slug).exists():
slug = f"{base_slug}-{counter}"
counter += 1
gallery = Gallery.objects.create(
title=title,
slug=slug,
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