75 lines
2.5 KiB
Python
75 lines
2.5 KiB
Python
from django import forms
|
|
import json
|
|
from decimal import Decimal
|
|
|
|
from apps.players.forms import PlayerSearchForm
|
|
|
|
from .models import SavedSearch
|
|
|
|
|
|
class SavedSearchForm(forms.ModelForm):
|
|
class Meta:
|
|
model = SavedSearch
|
|
fields = ["name", "is_public"]
|
|
widgets = {
|
|
"name": forms.TextInput(attrs={"placeholder": "e.g. EuroLeague guards under 24"}),
|
|
}
|
|
|
|
|
|
class SavedSearchUpdateForm(forms.ModelForm):
|
|
filters_json = forms.CharField(
|
|
required=False,
|
|
label="Filters (JSON)",
|
|
widget=forms.Textarea(attrs={"rows": 8, "class": "font-mono"}),
|
|
help_text="Structured search filters payload. Leave blank to keep current filters.",
|
|
)
|
|
|
|
class Meta:
|
|
model = SavedSearch
|
|
fields = ["name", "is_public", "filters_json"]
|
|
widgets = {
|
|
"name": forms.TextInput(attrs={"placeholder": "e.g. Italian wings - updated"}),
|
|
}
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
if self.instance and self.instance.pk and not self.initial.get("filters_json"):
|
|
self.initial["filters_json"] = json.dumps(self.instance.filters, indent=2, sort_keys=True)
|
|
|
|
def clean_filters_json(self):
|
|
raw = self.cleaned_data.get("filters_json")
|
|
if not raw:
|
|
return self.instance.filters
|
|
try:
|
|
parsed = json.loads(raw)
|
|
except json.JSONDecodeError as exc:
|
|
raise forms.ValidationError("Invalid JSON format.") from exc
|
|
|
|
if not isinstance(parsed, dict):
|
|
raise forms.ValidationError("Filters JSON must be an object.")
|
|
|
|
form = PlayerSearchForm(parsed)
|
|
if not form.is_valid():
|
|
raise forms.ValidationError("Filters JSON contains invalid search parameters.")
|
|
|
|
validated = {}
|
|
for key, value in form.cleaned_data.items():
|
|
if value in (None, ""):
|
|
continue
|
|
if hasattr(value, "pk"):
|
|
validated[key] = value.pk
|
|
elif isinstance(value, Decimal):
|
|
validated[key] = str(value)
|
|
else:
|
|
validated[key] = value
|
|
if not validated:
|
|
raise forms.ValidationError("Filters JSON does not contain valid searchable filters.")
|
|
return validated
|
|
|
|
def save(self, commit=True):
|
|
instance = super().save(commit=False)
|
|
instance.filters = self.cleaned_data["filters_json"]
|
|
if commit:
|
|
instance.save()
|
|
return instance
|