mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 06:11:07 -05:00
Ensure park and ride slugs are valid before displaying links
Prevents 500 errors by filtering out parks and rides with null or empty slugs from trending lists and excludes them from database queries where slugs are required. Additionally, it adds conditional rendering in templates to handle parks without slugs gracefully. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 0bdea3fb-49ea-4863-b501-fa6f5af0cbf0 Replit-Commit-Checkpoint-Type: intermediate_checkpoint
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
{% extends 'base/base.html' %}
|
||||
{% load static %}
|
||||
{% load cotton %}
|
||||
|
||||
{% block title %}ThrillWiki - Theme Parks & Attractions Guide{% endblock %}
|
||||
|
||||
@@ -71,30 +72,7 @@
|
||||
</h2>
|
||||
<div class="space-y-4">
|
||||
{% for park in popular_parks %}
|
||||
<a href="{% url 'parks:park_detail' park.slug %}"
|
||||
class="relative block h-48 overflow-hidden transition-all rounded-lg group hover:-translate-y-1 hover:shadow-xl"
|
||||
{% if park.photos.first %}
|
||||
style="background: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.7)), url('{{ park.photos.first.image.url }}') center/cover no-repeat;"
|
||||
{% else %}
|
||||
style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);"
|
||||
{% endif %}>
|
||||
<div class="absolute bottom-0 left-0 right-0 p-4 text-white">
|
||||
<div class="text-lg font-semibold">
|
||||
{{ park.name }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-200">
|
||||
{{ park.ride_count }} rides, {{ park.coaster_count }} coasters
|
||||
</div>
|
||||
{% if park.average_rating %}
|
||||
<div class="absolute top-0 right-0 p-2 text-yellow-400">
|
||||
<span class="mr-1">★</span>
|
||||
<span>{{ park.average_rating|floatformat:1 }}/10</span>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-sm text-gray-400">Rating not available</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
<c-park_card park=park view_mode="grid" class="h-48" />
|
||||
{% empty %}
|
||||
<div class="flex flex-col items-center justify-center h-48 p-8 text-center bg-gray-50 rounded-lg dark:bg-gray-800/50">
|
||||
<div class="mb-4 text-4xl">🎢</div>
|
||||
@@ -112,30 +90,7 @@
|
||||
</h2>
|
||||
<div class="space-y-4">
|
||||
{% for ride in popular_rides %}
|
||||
<a href="{% url 'parks:rides:ride_detail' ride.park.slug ride.slug %}"
|
||||
class="relative block h-48 overflow-hidden transition-all rounded-lg group hover:-translate-y-1 hover:shadow-xl"
|
||||
{% if ride.photos.first %}
|
||||
style="background: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.7)), url('{{ ride.photos.first.image.url }}') center/cover no-repeat;"
|
||||
{% else %}
|
||||
style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);"
|
||||
{% endif %}>
|
||||
<div class="absolute bottom-0 left-0 right-0 p-4 text-white">
|
||||
<div class="text-lg font-semibold">
|
||||
{{ ride.name }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-200">
|
||||
at {{ ride.park.name }}
|
||||
</div>
|
||||
{% if ride.average_rating %}
|
||||
<div class="flex items-center mt-1 text-yellow-400">
|
||||
<span class="mr-1">★</span>
|
||||
<span>{{ ride.average_rating|floatformat:1 }}/10</span>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="text-sm text-gray-400">Rating not available</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</a>
|
||||
<c-ride_card ride=ride class="h-48" url_variant="park" />
|
||||
{% empty %}
|
||||
<div class="flex flex-col items-center justify-center h-48 p-8 text-center bg-gray-50 rounded-lg dark:bg-gray-800/50">
|
||||
<div class="mb-4 text-4xl">🎠</div>
|
||||
@@ -155,48 +110,10 @@
|
||||
{% for item in highest_rated %}
|
||||
{% if item.park %}
|
||||
<!-- This is a ride -->
|
||||
<a href="{% url 'parks:rides:ride_detail' item.park.slug item.slug %}"
|
||||
class="relative block h-48 overflow-hidden transition-all rounded-lg group hover:-translate-y-1 hover:shadow-xl"
|
||||
{% if item.photos.first %}
|
||||
style="background: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.7)), url('{{ item.photos.first.image.url }}') center/cover no-repeat;"
|
||||
{% else %}
|
||||
style="background: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.7));"
|
||||
{% endif %}>
|
||||
<div class="absolute bottom-0 left-0 right-0 p-4 text-white">
|
||||
<div class="text-lg font-semibold">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-200">
|
||||
at {{ item.park.name }}
|
||||
</div>
|
||||
<div class="flex items-center mt-1 text-yellow-400">
|
||||
<span class="mr-1">★</span>
|
||||
<span>{{ item.average_rating|floatformat:1 }}/10</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<c-ride_card ride=item class="h-48" url_variant="park" />
|
||||
{% else %}
|
||||
<!-- This is a park -->
|
||||
<a href="{% url 'parks:park_detail' item.slug %}"
|
||||
class="relative block h-48 overflow-hidden transition-all rounded-lg group hover:-translate-y-1 hover:shadow-xl"
|
||||
{% if item.photos.first %}
|
||||
style="background: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.7)), url('{{ item.photos.first.image.url }}') center/cover no-repeat;"
|
||||
{% else %}
|
||||
style="background: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.7));"
|
||||
{% endif %}>
|
||||
<div class="absolute bottom-0 left-0 right-0 p-4 text-white">
|
||||
<div class="text-lg font-semibold">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-200">
|
||||
{{ item.ride_count }} rides, {{ item.coaster_count }} coasters
|
||||
</div>
|
||||
<div class="absolute top-0 right-0 p-2 text-yellow-400">
|
||||
<span class="mr-1">★</span>
|
||||
<span>{{ item.average_rating|floatformat:1 }}/10</span>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
<c-park_card park=item view_mode="grid" class="h-48" />
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<div class="flex flex-col items-center justify-center h-48 p-8 text-center bg-gray-50 rounded-lg dark:bg-gray-800/50">
|
||||
|
||||
Reference in New Issue
Block a user