.
This commit is contained in:
@@ -52,7 +52,7 @@
|
||||
<div class="buttons" style="margin-top:0.6rem">
|
||||
<button class="button is-small is-info" hx-get="{% url 'cards:edit' card.pk %}" hx-target="#htmx-form" hx-swap="innerHTML">Edit</button>
|
||||
<button class="button is-small is-primary" hx-get="{% url 'cards:preview' card.pk %}" hx-target="#modal-root" hx-swap="innerHTML">Preview</button>
|
||||
<button class="button is-small" hx-post="{% url 'cards:import' card.pk %}" hx-target="#htmx-form" hx-swap="innerHTML">Import Facts</button>
|
||||
|
||||
<button class="button is-small is-danger" hx-post="{% url 'cards:delete' card.pk %}" hx-confirm="Delete this card?" hx-target="#card-{{ card.pk }}" hx-swap="outerHTML">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+1
-2
@@ -8,8 +8,6 @@ urlpatterns = [
|
||||
path('create/', views.card_create, name='create'),
|
||||
path('<int:pk>/edit/', views.card_edit, name='edit'),
|
||||
path('<int:pk>/delete/', views.card_delete, name='delete'),
|
||||
path('<int:pk>/import/', views.import_facts_for_card, name='import'),
|
||||
path('<int:pk>/import/apply/', views.apply_import_for_card, name='import_apply'),
|
||||
path('preview/<int:pk>/', views.preview_card, name='preview'),
|
||||
path('backgrounds/', views.background_list, name='backgrounds'),
|
||||
path('backgrounds/create/', views.background_create, name='background_create'),
|
||||
@@ -21,4 +19,5 @@ urlpatterns = [
|
||||
path('export-table/', views.export_table, name='export_table'),
|
||||
path('import/paste/', views.import_from_paste, name='import_paste'),
|
||||
path('import/apply/', views.apply_bulk_import, name='import_apply_bulk'),
|
||||
|
||||
]
|
||||
|
||||
+1
-66
@@ -6,11 +6,7 @@ from .models import Dinosaur, BackgroundImage
|
||||
from .forms import DinosaurBulkFormSet
|
||||
from .forms import DinosaurForm
|
||||
from .forms import BackgroundImageForm
|
||||
from .llm import fetch_dinosaur_structured
|
||||
from decimal import Decimal
|
||||
import json
|
||||
import csv
|
||||
from io import StringIO
|
||||
|
||||
|
||||
def is_htmx(request):
|
||||
@@ -220,68 +216,6 @@ def preview_card(request, pk):
|
||||
return render(request, 'cards/preview.html', {'card': card, 'background': background})
|
||||
|
||||
|
||||
def import_facts_for_card(request, pk):
|
||||
"""Call an LLM to fetch suggested facts/stats for a single card and
|
||||
return an HTMX fragment showing a preview and an apply button."""
|
||||
card = get_object_or_404(Dinosaur, pk=pk)
|
||||
if request.method != 'POST':
|
||||
return HttpResponseBadRequest('Only POST allowed')
|
||||
try:
|
||||
suggestion = fetch_dinosaur_structured(card.name)
|
||||
except Exception as e:
|
||||
# Return a small fragment with the error so HTMX can render it in the form area
|
||||
return HttpResponse(render_to_string('cards/_import_preview.html', {'card': card, 'error': str(e)}, request=request))
|
||||
|
||||
# normalize fields for the template
|
||||
context = {'card': card, 'suggestion': suggestion}
|
||||
return HttpResponse(render_to_string('cards/_import_preview.html', context, request=request))
|
||||
|
||||
|
||||
def apply_import_for_card(request, pk):
|
||||
card = get_object_or_404(Dinosaur, pk=pk)
|
||||
if request.method != 'POST':
|
||||
return HttpResponseBadRequest('Only POST allowed')
|
||||
|
||||
# Read submitted values (form uses plain names)
|
||||
def _get_float(name):
|
||||
v = request.POST.get(name)
|
||||
if not v:
|
||||
return None
|
||||
try:
|
||||
return float(v)
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
speed = _get_float('speed_kmh')
|
||||
weight = _get_float('weight_kg')
|
||||
height = _get_float('height_m')
|
||||
intelligence = _get_float('intelligence_score')
|
||||
facts_text = request.POST.get('facts', '')
|
||||
|
||||
if speed is not None:
|
||||
card.speed = int(round(speed))
|
||||
if weight is not None:
|
||||
card.weight = int(round(weight))
|
||||
if height is not None:
|
||||
# store with one decimal place
|
||||
card.height = Decimal(str(round(height, 1)))
|
||||
if intelligence is not None:
|
||||
# Accept either a 1-5 scale or 0-100. Map 1-5 -> 0-100 if needed.
|
||||
if 0 <= intelligence <= 5:
|
||||
card.intelligence = int(round((intelligence / 5.0) * 100))
|
||||
else:
|
||||
card.intelligence = int(round(max(0, min(100, intelligence))))
|
||||
# Facts: accept multi-line textarea
|
||||
card.facts = '\n'.join([l.strip() for l in facts_text.splitlines() if l.strip()])
|
||||
card.save()
|
||||
|
||||
# Return refreshed card HTML to replace the item in the list and clear the form.
|
||||
background = BackgroundImage.get_active() if BackgroundImage.objects.exists() else None
|
||||
card_html = render_to_string('cards/_card_item.html', {'card': card, 'background': background}, request=request)
|
||||
oob = '<div id="htmx-form" hx-swap-oob="true"></div>'
|
||||
return HttpResponse(card_html + oob)
|
||||
|
||||
|
||||
def cards_overview(request):
|
||||
"""Overview page showing all cards in a table for quick edits."""
|
||||
backgrounds = BackgroundImage.objects.all()
|
||||
@@ -500,3 +434,4 @@ def apply_bulk_import(request):
|
||||
applied += 1
|
||||
|
||||
return HttpResponse(f'Applied updates to {applied} dinosaurs')
|
||||
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
django
|
||||
Pillow
|
||||
openai
|
||||
|
||||
Reference in New Issue
Block a user