Files
Faktenkompass/claims/forms.py
T
Pirmin Hinderling (fedora) 28aab3b16a Remove ambiguous evidence level field from claims and the AI assistant.
Drops Evidenzlevel from models, admin, public UI, and draft workflow while keeping Nachweise file uploads unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 22:11:47 +02:00

158 lines
5.8 KiB
Python

import json
from django import forms
from claims.models import Category, Claim, ClaimDraft
class AssistantInputForm(forms.Form):
article_url = forms.URLField(
label='Artikel-Link',
required=False,
widget=forms.URLInput(attrs={
'class': 'form-control',
'placeholder': 'https://beispiel.de/artikel',
}),
)
user_notes = forms.CharField(
label='Beschreibung / Behauptung',
required=False,
widget=forms.Textarea(attrs={
'class': 'form-control',
'rows': 4,
'placeholder': 'Welche Aussage soll überprüft werden? Kontext, Stichpunkte …',
}),
)
uploaded_file = forms.FileField(
label='Bild oder PDF',
required=False,
widget=forms.ClearableFileInput(attrs={'class': 'form-control', 'accept': '.jpg,.jpeg,.png,.gif,.webp,.svg,.pdf'}),
)
def clean(self):
cleaned = super().clean()
url = cleaned.get('article_url')
notes = (cleaned.get('user_notes') or '').strip()
uploaded = cleaned.get('uploaded_file')
if not url and not notes and not uploaded:
raise forms.ValidationError(
'Bitte mindestens einen Artikel-Link, eine Beschreibung oder eine Datei angeben.'
)
return cleaned
class ReviewDraftForm(forms.ModelForm):
tags_text = forms.CharField(
label='Schlagwörter',
required=False,
help_text='Kommagetrennt',
widget=forms.TextInput(attrs={'class': 'form-control'}),
)
sources_json = forms.CharField(
label='Quellen (JSON)',
required=False,
widget=forms.Textarea(attrs={'class': 'form-control font-monospace', 'rows': 6}),
)
counter_arguments_json = forms.CharField(
label='Gegenargumente (JSON)',
required=False,
widget=forms.Textarea(attrs={'class': 'form-control font-monospace', 'rows': 6}),
)
category_choice = forms.ModelChoiceField(
label='Bestehende Kategorie',
queryset=Category.objects.all(),
required=False,
empty_label='— Neue Kategorie verwenden —',
widget=forms.Select(attrs={'class': 'form-select'}),
)
class Meta:
model = ClaimDraft
fields = [
'title',
'claim_status',
'short_answer',
'detailed_explanation',
'new_category_name',
'new_category_description',
'new_category_icon',
]
widgets = {
'title': forms.TextInput(attrs={'class': 'form-control'}),
'claim_status': forms.Select(attrs={'class': 'form-select'}),
'short_answer': forms.Textarea(attrs={'class': 'form-control', 'rows': 4}),
'detailed_explanation': forms.Textarea(attrs={'class': 'form-control', 'rows': 6}),
'new_category_name': forms.TextInput(attrs={'class': 'form-control'}),
'new_category_description': forms.Textarea(attrs={'class': 'form-control', 'rows': 2}),
'new_category_icon': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'bi-book'}),
}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
instance = kwargs.get('instance') or getattr(self, 'instance', None)
if instance and instance.pk:
self.fields['tags_text'].initial = ', '.join(instance.tags or [])
self.fields['sources_json'].initial = json.dumps(
instance.sources or [], ensure_ascii=False, indent=2
)
self.fields['counter_arguments_json'].initial = json.dumps(
instance.counter_arguments or [], ensure_ascii=False, indent=2
)
if instance.category_slug:
category = Category.objects.filter(slug=instance.category_slug).first()
if category:
self.fields['category_choice'].initial = category
def clean_tags_text(self):
raw = self.cleaned_data.get('tags_text', '')
return [part.strip() for part in raw.split(',') if part.strip()]
def clean_sources_json(self):
raw = (self.cleaned_data.get('sources_json') or '').strip()
if not raw:
return []
try:
data = json.loads(raw)
except json.JSONDecodeError as exc:
raise forms.ValidationError('Ungültiges JSON für Quellen.') from exc
if not isinstance(data, list):
raise forms.ValidationError('Quellen müssen eine JSON-Liste sein.')
return data
def clean_counter_arguments_json(self):
raw = (self.cleaned_data.get('counter_arguments_json') or '').strip()
if not raw:
return []
try:
data = json.loads(raw)
except json.JSONDecodeError as exc:
raise forms.ValidationError('Ungültiges JSON für Gegenargumente.') from exc
if not isinstance(data, list):
raise forms.ValidationError('Gegenargumente müssen eine JSON-Liste sein.')
return data
def save(self, commit=True):
draft = super().save(commit=False)
draft.tags = self.cleaned_data['tags_text']
draft.sources = self.cleaned_data['sources_json']
draft.counter_arguments = self.cleaned_data['counter_arguments_json']
category = self.cleaned_data.get('category_choice')
if category:
draft.category_slug = category.slug
else:
draft.category_slug = ''
if commit:
draft.save()
return draft
class RefineDraftForm(forms.Form):
refinement = forms.CharField(
label='Überarbeitungswunsch',
widget=forms.Textarea(attrs={
'class': 'form-control',
'rows': 3,
'placeholder': 'z. B. „Kurzantwort kürzer formulieren“ oder „mehr Quellen hinzufügen“',
}),
)