diff --git a/cards/forms.py b/cards/forms.py
index f00090e..162a772 100644
--- a/cards/forms.py
+++ b/cards/forms.py
@@ -20,3 +20,17 @@ class DinosaurForm(forms.ModelForm):
'intelligence': forms.NumberInput(attrs={'class': 'input', 'min': 0, 'max': 100}),
'height': forms.NumberInput(attrs={'class': 'input', 'min': 0, 'max': 100}),
}
+
+
+from .models import BackgroundImage
+
+
+class BackgroundImageForm(forms.ModelForm):
+ class Meta:
+ model = BackgroundImage
+ fields = ['title', 'image', 'is_active']
+ widgets = {
+ 'title': forms.TextInput(attrs={'class': 'input', 'placeholder': 'Rocky desert'}),
+ 'image': forms.ClearableFileInput(attrs={'class': 'file-input'}),
+ 'is_active': forms.CheckboxInput(attrs={'class': 'checkbox'}),
+ }
diff --git a/cards/templates/cards/_background_form.html b/cards/templates/cards/_background_form.html
new file mode 100644
index 0000000..ccdfac7
--- /dev/null
+++ b/cards/templates/cards/_background_form.html
@@ -0,0 +1,55 @@
+{% load static %}
+
+
+
diff --git a/cards/templates/cards/_backgrounds_list.html b/cards/templates/cards/_backgrounds_list.html
new file mode 100644
index 0000000..62b0d20
--- /dev/null
+++ b/cards/templates/cards/_backgrounds_list.html
@@ -0,0 +1,25 @@
+
+
+ {% for bg in backgrounds %}
+
+
+
+
+
{{ bg.title }}
+
Uploaded {{ bg.uploaded_at }}
+
+ {% if not bg.is_active %}
+
+ {% else %}
+ Active
+ {% endif %}
+
+
+
+
+
+ {% empty %}
+
No backgrounds yet — upload one!
+ {% endfor %}
+
+
diff --git a/cards/templates/cards/backgrounds_list.html b/cards/templates/cards/backgrounds_list.html
new file mode 100644
index 0000000..192968c
--- /dev/null
+++ b/cards/templates/cards/backgrounds_list.html
@@ -0,0 +1,25 @@
+{% extends 'cards/base.html' %}
+
+{% block content %}
+
+
+
+
Background images
+
+
+
+
+
+
+
+ {% include 'cards/_background_form.html' with form=form %}
+
+
+
+
+ {% include 'cards/_backgrounds_list.html' with backgrounds=backgrounds %}
+
+
+
+
+{% endblock %}
diff --git a/cards/templates/cards/list.html b/cards/templates/cards/list.html
index 8b94514..b297575 100644
--- a/cards/templates/cards/list.html
+++ b/cards/templates/cards/list.html
@@ -6,6 +6,9 @@
+
diff --git a/cards/urls.py b/cards/urls.py
index 7d5519b..d07dd92 100644
--- a/cards/urls.py
+++ b/cards/urls.py
@@ -8,4 +8,8 @@ urlpatterns = [
path('create/', views.card_create, name='create'),
path('/edit/', views.card_edit, name='edit'),
path('/delete/', views.card_delete, name='delete'),
+ path('backgrounds/', views.background_list, name='backgrounds'),
+ path('backgrounds/create/', views.background_create, name='background_create'),
+ path('backgrounds//activate/', views.background_activate, name='background_activate'),
+ path('backgrounds//delete/', views.background_delete, name='background_delete'),
]
diff --git a/cards/views.py b/cards/views.py
index f0664ad..7593a80 100644
--- a/cards/views.py
+++ b/cards/views.py
@@ -3,6 +3,7 @@ from django.http import HttpResponse, HttpResponseBadRequest
from django.template.loader import render_to_string
from .models import Dinosaur, BackgroundImage
from .forms import DinosaurForm
+from .forms import BackgroundImageForm
def is_htmx(request):
@@ -75,3 +76,59 @@ def card_delete(request, pk):
return HttpResponse(status=204)
return redirect('cards:list')
return HttpResponseBadRequest('Only POST allowed')
+
+
+def background_list(request):
+ """Show existing backgrounds and provide a form to upload a new one."""
+ backgrounds = BackgroundImage.objects.all()
+ form = BackgroundImageForm()
+ if is_htmx(request):
+ return render(request, 'cards/_backgrounds_list.html', {'backgrounds': backgrounds, 'form': form})
+ return render(request, 'cards/backgrounds_list.html', {'backgrounds': backgrounds, 'form': form})
+
+
+def background_create(request):
+ if request.method != 'POST':
+ return HttpResponseBadRequest('Only POST allowed')
+
+ form = BackgroundImageForm(request.POST, request.FILES)
+ if form.is_valid():
+ bg = form.save()
+ # If marked active, unset others
+ if bg.is_active:
+ BackgroundImage.objects.exclude(pk=bg.pk).update(is_active=False)
+ if is_htmx(request):
+ # return the updated list fragment and clear the form OOB
+ list_html = render_to_string('cards/_backgrounds_list.html', {'backgrounds': BackgroundImage.objects.all(), 'form': BackgroundImageForm()}, request=request)
+ oob = f'{render_to_string("cards/_background_form.html", {"form": BackgroundImageForm()}, request=request)}
'
+ return HttpResponse(list_html + oob)
+ return redirect('cards:backgrounds')
+ else:
+ if is_htmx(request):
+ form_html = render_to_string('cards/_background_form.html', {'form': form}, request=request)
+ oob = f'{form_html}
'
+ return HttpResponse(oob)
+ return render(request, 'cards/backgrounds_list.html', {'backgrounds': BackgroundImage.objects.all(), 'form': form})
+
+
+def background_activate(request, pk):
+ if request.method != 'POST':
+ return HttpResponseBadRequest('Only POST allowed')
+ bg = get_object_or_404(BackgroundImage, pk=pk)
+ BackgroundImage.objects.update(is_active=False)
+ bg.is_active = True
+ bg.save()
+ if is_htmx(request):
+ list_html = render_to_string('cards/_backgrounds_list.html', {'backgrounds': BackgroundImage.objects.all(), 'form': BackgroundImageForm()}, request=request)
+ return HttpResponse(list_html)
+ return redirect('cards:backgrounds')
+
+
+def background_delete(request, pk):
+ if request.method != 'POST':
+ return HttpResponseBadRequest('Only POST allowed')
+ bg = get_object_or_404(BackgroundImage, pk=pk)
+ bg.delete()
+ if is_htmx(request):
+ return HttpResponse(status=204)
+ return redirect('cards:backgrounds')
diff --git a/db.sqlite3 b/db.sqlite3
index eeddcfd..3d42d20 100644
Binary files a/db.sqlite3 and b/db.sqlite3 differ
diff --git a/media/backgrounds/Gemini_Generated_Image_3x5wer3x5wer3x5w.png b/media/backgrounds/Gemini_Generated_Image_3x5wer3x5wer3x5w.png
new file mode 100644
index 0000000..d782aa0
Binary files /dev/null and b/media/backgrounds/Gemini_Generated_Image_3x5wer3x5wer3x5w.png differ
diff --git a/media/backgrounds/Gemini_Generated_Image_z0dte7z0dte7z0dt.png b/media/backgrounds/Gemini_Generated_Image_z0dte7z0dte7z0dt.png
new file mode 100644
index 0000000..80cca82
Binary files /dev/null and b/media/backgrounds/Gemini_Generated_Image_z0dte7z0dte7z0dt.png differ
diff --git a/templates/cards/list.html b/templates/cards/list.html
index 8b94514..b297575 100644
--- a/templates/cards/list.html
+++ b/templates/cards/list.html
@@ -6,6 +6,9 @@
+