diff --git a/parks/__pycache__/urls.cpython-312.pyc b/parks/__pycache__/urls.cpython-312.pyc index 46b45eb7..03333a7c 100644 Binary files a/parks/__pycache__/urls.cpython-312.pyc and b/parks/__pycache__/urls.cpython-312.pyc differ diff --git a/parks/__pycache__/views.cpython-312.pyc b/parks/__pycache__/views.cpython-312.pyc index a2256e29..5f4885e1 100644 Binary files a/parks/__pycache__/views.cpython-312.pyc and b/parks/__pycache__/views.cpython-312.pyc differ diff --git a/parks/urls.py b/parks/urls.py index 5a215ac3..20dcc4ec 100644 --- a/parks/urls.py +++ b/parks/urls.py @@ -8,6 +8,8 @@ urlpatterns = [ path('', views.ParkListView.as_view(), name='park_list'), path('create/', views.ParkCreateView.as_view(), name='park_create'), path('rides/', RideListView.as_view(), name='all_rides'), # Global rides list + path('countries/search/', views.search_countries, name='search_countries'), + path('countries/select/', views.select_country, name='select_country'), path('/', views.ParkDetailView.as_view(), name='park_detail'), path('/rides/', include('rides.urls', namespace='rides')), ] diff --git a/parks/views.py b/parks/views.py index 2dbcf5ce..f8adc786 100644 --- a/parks/views.py +++ b/parks/views.py @@ -1,15 +1,17 @@ from django.views.generic import DetailView, ListView, CreateView -from django.shortcuts import get_object_or_404 +from django.shortcuts import get_object_or_404, render from django.core.serializers.json import DjangoJSONEncoder from django.urls import reverse +from django.db.models import Q from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.contenttypes.models import ContentType -from django.http import JsonResponse, HttpResponseRedirect +from django.http import JsonResponse, HttpResponseRedirect, HttpResponse from .models import Park, ParkArea from rides.models import Ride from core.views import SlugRedirectMixin from moderation.mixins import EditSubmissionMixin, PhotoSubmissionMixin, InlineEditMixin, HistoryMixin from moderation.models import EditSubmission +import pycountry class ParkCreateView(LoginRequiredMixin, CreateView): model = Park @@ -42,6 +44,37 @@ class ParkCreateView(LoginRequiredMixin, CreateView): def get_success_url(self): return reverse('park_detail', kwargs={'slug': self.object.slug}) +def search_countries(request): + query = request.GET.get('q', '').strip() + countries = [] + + if query: + # Use pycountry's search functionality for fuzzy matching + try: + # Try exact search first + country = pycountry.countries.get(name=query) + if country: + countries = [country] + else: + # If no exact match, try fuzzy search + countries = pycountry.countries.search_fuzzy(query) + except LookupError: + # If search fails, fallback to manual filtering + countries = [ + country for country in pycountry.countries + if query.lower() in country.name.lower() + ] + + return render(request, 'parks/partials/country_search_results.html', { + 'countries': countries[:10] # Limit to top 10 results + }) + +def select_country(request): + if request.method == 'POST': + country = request.POST.get('country', '') + return HttpResponse(country) + return HttpResponse('Invalid request', status=400) + class ParkDetailView(SlugRedirectMixin, EditSubmissionMixin, PhotoSubmissionMixin, InlineEditMixin, HistoryMixin, DetailView): model = Park template_name = 'parks/park_detail.html' @@ -106,13 +139,15 @@ class ParkListView(ListView): def get_queryset(self): queryset = Park.objects.select_related('owner').prefetch_related('photos', 'rides') - # Apply filters - search = self.request.GET.get('search', '').strip() - location = self.request.GET.get('location', '').strip() - status = self.request.GET.get('status', '').strip() + search = self.request.GET.get('search', '').strip() or None + location = self.request.GET.get('location', '').strip() or None + status = self.request.GET.get('status', '').strip() or None if search: - queryset = queryset.filter(name__icontains=search) | queryset.filter(location__icontains=search) + queryset = queryset.filter( + Q(name__icontains=search) | + Q(location__icontains=search) + ) if location: queryset = queryset.filter(location=location) if status: diff --git a/templates/parks/park_form.html b/templates/parks/park_form.html index 2c0dd8af..35beb6ea 100644 --- a/templates/parks/park_form.html +++ b/templates/parks/park_form.html @@ -17,7 +17,21 @@ - {% if field.field.widget.input_type == 'text' or field.field.widget.input_type == 'date' %} + {% if field.name == 'country' %} +
+ +
+
+ {% elif field.field.widget.input_type == 'text' or field.field.widget.input_type == 'date' %}
-
+
Relocated
-
- -
-
- {% for park in parks %} -
- {% if park.photos.exists %} -
- {{ park.name }} -
- {% endif %} -
-

- - {{ park.name }} - -

-

- - {{ park.location }} -

-
- - {{ park.get_status_display }} - - {% if park.average_rating %} - - - {{ park.average_rating|floatformat:1 }}/10 - - {% endif %} -
- -
-
- {% empty %} -
-

No parks found matching your criteria.

-
- {% endfor %} +
+ {% include "parks/partials/park_list.html" %}
- - - {% if is_paginated %} -
-
- {% if page_obj.has_previous %} - « First - Previous - {% endif %} - - - Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }} - - - {% if page_obj.has_next %} - Next - Last » - {% endif %} -
-
- {% endif %}
{% endblock %} diff --git a/templates/parks/partials/country_search_results.html b/templates/parks/partials/country_search_results.html new file mode 100644 index 00000000..a72cc2c8 --- /dev/null +++ b/templates/parks/partials/country_search_results.html @@ -0,0 +1,15 @@ +
+ {% for country in countries %} +
+ {{ country.name }} +
+ {% empty %} +
+ No countries found +
+ {% endfor %} +
diff --git a/templates/parks/partials/park_list.html b/templates/parks/partials/park_list.html index a78a2b66..9962749f 100644 --- a/templates/parks/partials/park_list.html +++ b/templates/parks/partials/park_list.html @@ -1,48 +1,78 @@ -{% for park in parks %} -
- {% if park.photos.first %} - {{ park.name }} - {% else %} -
- No image available -
- {% endif %} - -
-

- {{ park.name }} -

-

{{ park.location }}

-
- - {{ park.rides.count }} attractions - - {% if park.average_rating %} -
- - {{ park.average_rating|floatformat:1 }}/10 + +
+ {% for park in parks %} +
+ {% if park.photos.exists %} +
+ {{ park.name }}
{% endif %} -
- {% if park.status != 'OPERATING' %} -
- - {{ park.get_status_display }} - +
+

+ + {{ park.name }} + +

+

+ + {{ park.location }} +

+
+ + {{ park.get_status_display }} + + {% if park.average_rating %} + + + {{ park.average_rating|floatformat:1 }}/10 + + {% endif %} +
+
+
+ {% empty %} +
+

No parks found matching your criteria.

+
+ {% endfor %} +
+ + +{% if is_paginated %} +
+
+ {% if page_obj.has_previous %} + « First + Previous + {% endif %} + + + Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }} + + + {% if page_obj.has_next %} + Next + Last » {% endif %}
-{% empty %} -
-

No parks found matching your criteria.

-
-{% endfor %} +{% endif %} diff --git a/thrillwiki/__pycache__/settings.cpython-312.pyc b/thrillwiki/__pycache__/settings.cpython-312.pyc index 379b17ce..6c88a354 100644 Binary files a/thrillwiki/__pycache__/settings.cpython-312.pyc and b/thrillwiki/__pycache__/settings.cpython-312.pyc differ diff --git a/thrillwiki/settings.py b/thrillwiki/settings.py index 1e500f17..d0adedf8 100644 --- a/thrillwiki/settings.py +++ b/thrillwiki/settings.py @@ -12,7 +12,7 @@ SECRET_KEY = 'django-insecure-=0)^0#h#k$0@$8$ys=^$0#h#k$0@$8$ys=^' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'thrillwiki.com'] +ALLOWED_HOSTS = ['localhost', '127.0.0.1', 'thrillwiki.com', 'beta.thrillwiki.com'] # Application definition INSTALLED_APPS = [