From 77aa70f611c63e8c4a91e48965a67eaafa3abd0e Mon Sep 17 00:00:00 2001 From: pacnpal <183241239+pacnpal@users.noreply.github.com> Date: Wed, 30 Oct 2024 20:04:04 +0000 Subject: [PATCH] pycountry integration? --- parks/__pycache__/urls.cpython-312.pyc | Bin 969 -> 1171 bytes parks/__pycache__/views.cpython-312.pyc | Bin 8931 -> 10435 bytes parks/urls.py | 2 + parks/views.py | 49 ++++++-- templates/parks/park_form.html | 16 ++- templates/parks/park_list.html | 89 ++------------ .../partials/country_search_results.html | 15 +++ templates/parks/partials/park_list.html | 114 +++++++++++------- .../__pycache__/settings.cpython-312.pyc | Bin 5643 -> 5664 bytes thrillwiki/settings.py | 2 +- 10 files changed, 154 insertions(+), 133 deletions(-) create mode 100644 templates/parks/partials/country_search_results.html diff --git a/parks/__pycache__/urls.cpython-312.pyc b/parks/__pycache__/urls.cpython-312.pyc index 46b45eb7ce307dec0a169337d67e0d35f0f8fbc2..03333a7c533cdf6f6fe60a0837301076accc3191 100644 GIT binary patch delta 337 zcmX@fKABVfG%qg~0}w1IRZ5@9#K7ne~C?_?!ME@3FaVm%bRa80oJ7X9l|71U= z6s{sZpj}1$Kw|PHraUe=AcGNzi}z2~V$M{(z$r5$^}3wNMLClT*1lI*{BE*vK*fwM c${Ag-^t{62HF*NF9ydP+KT{)jkql5T0EJLb`v3p{ delta 153 zcmbQtd6HfIG%qg~0}xEiP)h&H$iVOz#DM{BDC2X`Ms;?^$#smf#(ZlyRx?9{nHW+T zQ}}@-Q;I-};2NRTOb~Gxoz5D?Qz@(|GWi^1)#M3Gp^UtfpE0FO4q?vYk^!m&TE$IjnZx1qG{Fs+FEV@OxhrHg1!c2-6n1OFHNY{RhzVP?lUxv zD(y*}cYMyd=iYZde&_Pn18*Pq{Jy%nioo-&@zl@VhZh5xiaV7JONs;2l~`!JqXP0@*+zm<@u=sZ?pT zg-|wB2xr5>#-&9H(QH)kZmq5m%f^5&6Qx?KFT}I)LPNHpkjN$q$!t;>d9=ntDw`6# zS8K{PNu-A;zDq=@Q9Y`B-GX03NVZw=Un1ESB>;4junB@qtr}C~YJ-|klPbOLsMw~3 zJ_P!(sc(D0pj8+|z#yth*X7Ex%mr_zjvu0J^^#FDq?Y=Nr$*EqyjcI%hqoFwrj9Bq z<1@5LqR07bbQ6{NA8E74a33s{#-393vErz%@_Y1~w2vplp&Q?kxJ;A0)7ID64tuZ; zAck{nfSvBw@_H!~Fzie{Gp_0-*2!P7MW~1W(zc~Hie`3mbKS7zm^x5WnH#0mc&tG< zP@$-(8mmE><=D{^PctX58H-`jRc+9)fJuSvI!J$npEFOX}L?Sq$2 zfh5^}6z||UXA^DbFFMn-oB!1L5Ut_wIaA34LJ8y=Vcp0J>lkuKd^}#&+9(wGGlw46 zAIt{^_ulU)e_oD3xPB%FEsAtq;z?H>KWcGS(IGM=O;XnF$mKiq#H`96jhcvDJ}0UC-(X(nLxaJMlCVc8tPK ziQs;6S$a#35qZxajLC>(wut|opdU#E=VV?C)pr!nPrg!FwC@m7fEH zPPF_BkZH2w4qQI`(&5WTUphM9b=AM*ZeDh`ExOy5-0jl`R($^H-uLb9JCo8~d!Evy->%v94fJek=88SIG8ut)nX`zn!2!`K#fOG((`G z>l_L_-3pD6<~~;&ua0=iC5*RtJ}J`^Fc)Zl4)~-K;f__;D^YEsGkXM@95b9 zEw3ai*pQ!vUVw&e1T*MxTR|-i7Zr2WZd~d`g(Om3HuH+^*R$#YL_icANI|zUJ zULcTCyXVD=&tIGm-LxlG{Lw4zbM4Fi)S^Fib?0lRmi&***l&4b^F2%6<^@OdEmwFU zl6j-)9oO~+%XR?=Iq=XriTxKkm2zRkFJdm^^Y^H|Ma;5HpGsi(1k#D z3c3Mw8Cigl;SlAit0e(ZIwFUtP5!Z~jh^5w?&APVdjioLvu=q}mGkOG`V{{~bz&=` z0K@MwY=e0Xz)~O`>}-BIQ#C+Ph55nanni5J4snO4(I&9$4Da+b+p?h4$GFxI;j_Ul z{QI6Z*zFIVmKX+$J%!{jnjkP$8YaS%wGqC_n<-;Z?^%IBK)v-MFxO~b#>I|+j6I2@ z4+#Rc2mm_>>ByCUtOL@t`DJJLp7c`#O@mb_*8!Re`^oYY2F>$Ru%#MDz2!0FrR+(iv=z6$tIB- zM)K(-vah2|oa7>K_h)Y!HAwInI$je#x&$~I1UwD4Pd~X*m*gLZ;$~8(A*pjd8`y}c zdJ@|F3MuhoZ3Dj*{(=2G)nPy>d^(c%RCpY0WW*un*|#IDye*o}Zm2Ai5^IIIhei3o zbKhK*UU#g|+fPZI>(U8;Jd@|&i+-sk39by=*l@8_)I|*#Hgm2BbYpQ)vqs)f_i$OT zUxDA5Dzh>6q7I9}@QpEbP%Vi$Y4$D-F!lu`0`pEHCn`t`OzVBcI)^HA8{l;8N`R3H z95U>KiRdwy&9Ng;=AX~2=Q5AEe$@+aB9WeKq(JbMfWmB;6DTX&U&fpRXH$VY$y4hW> zPrA#n;JvaEO#YvEOVa~k`^+ZW-;koO@S%oZL2soJ^T!dIOrIF)OeMDH$*=%`>n4nd zwpP$j@ZqX_G z);4*p;eREq)@^qP5c95z7MV7_l-wgRJ9jsx+8iJ;T*}D6=uoi(hLSFB&W5idQBHM; ztF_Lm_`b#@b@5Y;tz~idUSBi}mwi?ZZkPuNPG17%6 zGPUC@RGiL&D5$|zOeDXfkUyV?5~u|^3n2+3i3l@pN%_n8Ujcg-Nel_z%ovUxf&2nN zL_ADP6p*zaw1#63Y%;E?kFy`cPaIzQcY)lIDW$i`zD2U{Hrc*PcCC`cDrs0HJAuDV z4la^|w@GT1#8*k{Z8Eq-ng>@&`+LNbt!|AVd-w4$wcp)hp^vS(`IXdO Q?`FDfcE^VVULpto1CUjJhyVZp delta 2450 zcmaJ?S!^3s6rJZ~9LMn%J6;ppahfJhAYy3{M5Usnp)FklfmTC_G4@O1W+o1AoOEGv zgpepgEa4)7Kv4c5Z9hQe10f+55b(iIp+8}ysFX$G2dU7q2tMH6H)$!T!m`fXckf&7 zJ9l{>kA6E6_}uSrR`9ntm7g4mEd~-Sv)I$sU`j=)ICa(VXdWrM^d`frd8O>un+>1l zld`I}7=Fz!Wse>(f?CiBX(1dpRlIuGXw_Pch!&CdW<6@OX>C&W=`ka&#iiV$Cyb<) zG*Vj1NNZ`MU2C*UgJ173GFpZy4rQ}a2|S@xg51ZQ$6e&HqG(yE51~HH<2=bzJk8rV zJKnTv&q;eL+9OxBcS?H{?QPs~+_}0ce<tF$cIDYv3lw3-D}v?BrPoI9Ugn>dv78ZY25T^bRV6fsP)oSh(vAONN2UR4?r@N|3fHr1?qfFqgh$!%$?wBy z#_j?Z=^WdI6ADe1+nk%_!V1xj<=RZ0AFLNErFuz(&@P7PGvD%pRg?FYtcFdxqjkI|&dfv}Iemvna#P!?D%n`+$L zS*wp6qzqMU7WR<&A%Yq#$5;8-3xCD)>`urhoJmP+moyqg}JlnFdVEByZr7G=n4ut=&B+(Yp1 zsELE5+fOi!aAmj*QW9)}-R*;RxC{)}Vu)yw1BL9q?hZ6r>g-gl zUNdEsEY;*CQJxZgXb~xb3>?c|mn5;kM20?IJ3Xm%!~^hCHg?DLC|b_VBV%?+yRn5; zXJuFm?kjTUF$x0!oa=@kbKQj_ z>N#I{Ii7u~vDkQf{`tn4_=Z!7&$1t8PxI+h*)tpUFXH-_Im5g{HYpx$=%O#Y@T&mIQ%n)fl2Ppx@*bO+6pWkG8$5hf{hVM8?S5|tHxiLuqH zp!tVGyYU6tj(*%*$ z<;ZS8S!*?|$F1jdzCpZ-Ln=4(DTMP*#@Jb9;}^=t6=h&W8Cp@YE6Ob>oTYz$Md?^k vde15oXOxK*<(iAG4z`t@ZtHm~bx|SFad872=)E=A&jz2r`4/', 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 379b17ce280f0301e144ecf7bda936d5b205814f..6c88a3544047d75f13d909978c7ff48f7667bbe3 100644 GIT binary patch delta 48 zcmeCyS)jvvnwOW00SKhKl+w*M@^&#ZvP_=Atj1m?oRnIUsJD3o^F4mX;LZKQHB102 CD-B=( delta 40 vcmZ3W)2+jMnwOW00SG2$D5cA9