From 10956c32dc15ac399c5862dd9d7e9f420a32c4f1 Mon Sep 17 00:00:00 2001 From: Junwei Zhao Date: Sun, 8 Sep 2024 20:34:31 +1000 Subject: [PATCH] Add standalone search page --- README.md | 50 ++++++++++++++++++ db.sqlite3 => data/db.sqlite3 | Bin links/__pycache__/urls.cpython-312.pyc | Bin 1142 -> 1266 bytes links/__pycache__/views.cpython-312.pyc | Bin 9086 -> 9902 bytes links/templates/links/search.html | 43 +++++++++++++++ links/urls.py | 1 + links/views.py | 14 ++++- locale/zh_Hans/LC_MESSAGES/django.mo | Bin 1673 -> 1988 bytes locale/zh_Hans/LC_MESSAGES/django.po | 18 +++++++ new_theme/static/css/dist/styles.css | 43 +++++++++++++++ templates/base.html | 1 + .../__pycache__/settings.cpython-312.pyc | Bin 2201 -> 2208 bytes url_manager/settings.py | 3 +- 13 files changed, 171 insertions(+), 2 deletions(-) rename db.sqlite3 => data/db.sqlite3 (100%) create mode 100644 links/templates/links/search.html diff --git a/README.md b/README.md index 0314620..7680786 100644 --- a/README.md +++ b/README.md @@ -74,3 +74,53 @@ Contributions are welcome! Please feel free to submit a Pull Request. ## License This project is licensed under the MIT License. + +## Local Development + +To run the URL Manager locally: + +1. Clone the repository: + ``` + git clone https://github.com/yourusername/url-manager.git + cd url-manager + ``` + +2. Create and activate a virtual environment: + ``` + python -m venv venv + source venv/bin/activate # On Windows, use `venv\Scripts\activate` + ``` + +3. Install dependencies: + ``` + pip install -r requirements.txt + ``` + +4. Apply database migrations: + ``` + python manage.py migrate + ``` + +5. Create a superuser: + ``` + python manage.py createsuperuser + ``` + +6. Compile translation messages: + ``` + python manage.py compilemessages + ``` + +7. In one terminal, start the Tailwind CSS build process: + ``` + python manage.py tailwind start + ``` + +8. In another terminal, run the Django development server: + ``` + python manage.py runserver + ``` + +9. Open your browser and go to `http://127.0.0.1:8000` + +Remember to keep both the Tailwind CSS build process and the Django development server running while you're developing. diff --git a/db.sqlite3 b/data/db.sqlite3 similarity index 100% rename from db.sqlite3 rename to data/db.sqlite3 diff --git a/links/__pycache__/urls.cpython-312.pyc b/links/__pycache__/urls.cpython-312.pyc index 14acbfb95228330ae161ebb358e6705bb5ebf76e..23349218b26a3b40a502bcbe853419b782398f4c 100644 GIT binary patch delta 232 zcmeyy@rhI8G%qg~0}!mLzMHm?iGkrUhyw#WP{wBtri~g~7$+vkS_`dVTg?m+W@1QX zOc73H&XRzsN6;xE2zBWkQM{F+nqrebFdi3RFHTJ?O3u)~#Rg$a-o~WH$T#^eQw85G zu3)fSSY~Q@5&z_HW)ChIpoxq?T>N12O6E;wk`r97i>O=_QMoRnb5TU+vWVV>h$}31 jH(5A3c&Tv9+Cj6hs`bTSvqCTY1DqSqyjFG?C;unM@s68M3i NgP*C9yGR140s!5E9RmOW diff --git a/links/__pycache__/views.cpython-312.pyc b/links/__pycache__/views.cpython-312.pyc index 40b9a921edd7fb771217f864906d38bd629b63dd..5ed414097fb70ef40ad13f5528e3ec83fa862366 100644 GIT binary patch delta 2758 zcmai0Yiu0V6`t#TdS709*K4mI>qktSaj+fALy$mlAg&t{Csq>zj75g^&b2+s%#JxT z8$wtxAgj17Q4?K7R)18Lsz@{>LP8d(?VtXsgb)&HL?q}46#n#2C90?|T7DqTxnpnA zD8NYm_RM$AJ@?LeU4Q+x04ajV1b)H0rNi#?2#c1V`OCkCOMbU;O+lFk8M;q)m$>x!5=dlK>O16M(2ah+{5uTHxn#hYwr!cQIH_L5ch`10S^YHJ@M&H-T{NdMMaH(N_=*K zdwRvGdi<298)dHy+iA_61fvLQ7DDS0?z(ynEZ9l3bSjTIMXyuhnbfvm zrzs(KO3g-pM4El;@wCdOWq1PTC(D*;Ko|K<+32*qz;(l{cz(q6xa~p*X(AlJ0U16& zCC_A5%y@%u3`{jr&oXdy9?% zPvff}!z#8+*Mpq+LvDy|7uRyd4$8IPVsMLlTzB!O;&B7!MN9rEtWh)nNV+scFygY9{XB5P1l&>g z9NhtP!K{`ou*Dbc$8hfh1z_g-9}DlZu0?X4s90v@1UK}ur{W>74Y8KQZ#u^(DI{uE zwkqsGd1HT)Dzq}{%pJ#F{CK%qbv#)R2Fsl85s8S>%Z@Njfq2r!tx+4cuiSTxS}yb(V7gVg;te$W;CtD zweYHPifNI40hoz6BCV%d9E0v);9(WyF^lYm_&9?baZzu8ZpZ`HP&(;*Lq5Wy3 zuAITCY{X2Z&Mq*KX+9WzF;ox1gt(sn!Lmo?A)k8aa_G{=y8mOto9t=)&Q1Bna6Mda zG9pwt^$v)|o&b=#gl?fLVu%GJHbm2JjHdA>UNN#D@w)Y+*ksh*ppmcnXAUL$zATSlmy zWZ&KZYvUA%HH4qhv1r=-cSZRmKm79am*H5XTIm>aVl9C9wmQ6)P*E8ZLE9||VHhEfhQ8eV>c?j~2>olqCa!NFx3 z4Sr_BAGIKubHSa~+}H#<$*6PlES_n(V;+>NF8*_3I#no=n(2O_;Rg5^KULvNq;`YL zbMsRcJ#R@iEYPL@49E*v-XXL24)X-m{2&L%d6FnBx7_1j#UI3vt66+Eyn$M(W%m~d q*F%i4Ys$nGW#XE$@UgNWVq5IOKel$W(SPksu#U4m|5orvhWi^gw|QFt delta 2091 zcmah}U2GIp6rO4Kulv{ScDLPaOS=m#bP8=XlqeOk{!kDQPz1tA7^gdzcIcg1ICmCG zG^s`sdGMv&#F!W#d~8gN+JqOMOf)9?M2rtkf{i|y$dieQCTNW3+-(aI(S7*#-0z%w z&Y5%0Js&>z*L3#lOeU$}@5}SI&b?Py%9iwFOWSrX>YAfDtvu_$R%b7XFMR|vpH}fdRoH+0F3TDA8nniU^@Gh_0>{fPdykwTpXOfq_9p=se6zR3+@j=mKIjdZL%P#Rn6&O(GOZFe@!#D zDmIU7CyQ;c+Z0cyL?$Mrgk`eD34xgGd9V$ z^-(=4Ki4N$(k-_mu?z-<&GOIKxL%bz;)ir&Wg+gjEDjJ~K?u{e1_1K|OVlBNsAU1_$q_v-tEusa4Mih_8Oy41TZkIt+_IMSrUM;SQ_ahLWZEZR zPmRZRHN_jLS5H1p;$DI$2=W9|1OL>FXw+&<2&(}cb`z}}suZW` zI4!TGhnrER<&AU@+fVF)m4`Bho>ygQI=*Cc*MYK}&z3V?Hs5hDO=dB>Jp(0 zLY;-tb1vgf7*iGkULcREMsbv|M)+H+($SUgvv27y9YNlR!znU+o`51W@2M709&jAN zh^ZF9i$t6xP=7gJ;BfZ^xvwoIIW^_={FbIubLG=~o8C`ejYJspSTI+2 z;0zwaI8H2gMF4sEW9MKm)hbL2##t?3j^#Q+v>;Wfz=W(8iaL{z6i(wzE){;?T|os5 z5p*Cd>tTeu{=AWdC~<1G)C(h%Fe26{lIlu@&T|NYb^ul#!`vzM=v)@N z&SIFL3-mepN22^m_eZ)uD?cuk^o#PV()d35Vk4(s9ZZs!rfZUB5W-k}<~)8wn6Q1n z9@qhcoT70E8%#i!49Dc&a`j*lMVuU(KX{B_4?zPV%+ZlWp5skzgm#Y60u}j9|FIJrODT+E``rs+^a8kk06l0NwsPh- zTWI4^l@!`Z5~R(~G+gdj_Kc|WM!;}0xR54oMJ^2VA5udUz1U!I1vZg=9GGbEK&V#3 zHL^T`Anrb9Y&;oe1+$?xXQ|J?HeFx&Vc<=@#Tb)k29NCuQ_gwYpRJGKCK75nsi0sr{+%exLy7+TBT#N-^`-0nnTlb+Pmxcxw%Ve~k@LUjFP=y7xm(|)-FJHY>hNeJ0 z0@e8IB>nS6-%0Gj#N$-O>JsbJN>P8dQ}@;)rN0s!*XJ) Nll*mSuRf~Q_1_e1=qmsK diff --git a/links/templates/links/search.html b/links/templates/links/search.html new file mode 100644 index 0000000..de94ac6 --- /dev/null +++ b/links/templates/links/search.html @@ -0,0 +1,43 @@ +{% extends 'base.html' %} +{% load i18n %} + +{% block content %} +
+
+
+

{% trans "Search Links" %}

+
+
+
+
+ + +
+
+ + {% if query %} +

{% trans "Search Results for" %} "{{ query }}"

+ {% if links %} +
    + {% for link in links %} +
  • +
    +
    + {{ link.alias }} +

    {{ link.original_url }}

    +
    +
    + {% trans "Clicks" %}: {{ link.click_count }} +
    +
    +
  • + {% endfor %} +
+ {% else %} +

{% trans "No results found." %}

+ {% endif %} + {% endif %} +
+
+
+{% endblock %} diff --git a/links/urls.py b/links/urls.py index 52d5d25..43b081a 100644 --- a/links/urls.py +++ b/links/urls.py @@ -8,5 +8,6 @@ urlpatterns = [ path('delete//', views.LinkDeleteView.as_view(), name='link_delete'), path('delete-selected/', views.delete_selected, name='delete_selected'), path('detail//', views.LinkDetailView.as_view(), name='link_detail'), + path('search/', views.SearchView.as_view(), name='search'), path('/', views.redirect_to_original, name='redirect_to_original'), ] diff --git a/links/views.py b/links/views.py index 4bcad98..786d838 100644 --- a/links/views.py +++ b/links/views.py @@ -1,5 +1,5 @@ from django.shortcuts import render, redirect, get_object_or_404 -from django.views.generic import ListView, CreateView, UpdateView, DeleteView, DetailView +from django.views.generic import ListView, CreateView, UpdateView, DeleteView, DetailView, TemplateView from django.urls import reverse_lazy, reverse # Add 'reverse' here from django.db.models import F, Count, Q from django.db.models.functions import TruncDate @@ -134,3 +134,15 @@ def search_aliases(request): print(f"Search results: {results}") # Debug print return JsonResponse(results, safe=False) + +class SearchView(TemplateView): + template_name = 'links/search.html' + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + query = self.request.GET.get('q', '') + if query: + links = Link.objects.filter(Q(alias__icontains=query) | Q(original_url__icontains=query)) + context['links'] = links + context['query'] = query + return context diff --git a/locale/zh_Hans/LC_MESSAGES/django.mo b/locale/zh_Hans/LC_MESSAGES/django.mo index 031bc9159c6b4c9d78a109670a52c762a7a35dff..326b3c816db60a4546b46cf88c9a4476666ff3d0 100644 GIT binary patch delta 1002 zcmY+CO=uHQ5XUD;lWJ`n8(Tk`s;l(i7Zp4dYEL<+P-?{%d-2jWSV+m9Rl0I7~t_z%g4QH1NnG4O}=g1j#Ya-9Pp zuOHp;Euzzyj36)r^1?E>1+0Ml#dUBLU2#D!_zTzPbs;$HcVid?`@}yEay})T5S|CQ z6It=EfH9m;^OCs50r-ya3CM-2;;({y16Sf7g=-T3Cj1R@2Yb*~Oerbc4|2VOAb-d( zXz}EvB&NY(_-R>CmUvaT3ZfCz1?_-#K`rC=gY-t>-5?*t?}3fm&4xcjdmuEjWfpZ~ znuPdKZHKl&e9OJiPKa;7zoQS@1ocB~{A<{H1N=Ag+vUfs{1fGlP%2&2^G1PEnK{)+ zYZ)arrKx5*YiGmt#0jIQnTndz)q;{Ym2;Ehc7NpX*hF42wZd$!SWqtJXN}AdoiX)G zx}oNH2~DYU8U4WxFG0{Q-)Fpp5_k delta 657 zcmXYuF)Tw-6ozlx=T%izTiQ~#N}47XgG5Xn3=)G_OoEsyq5}y-la6BbSeVQfX%k5| z3F#n2tQ~A(F`C5S`=4`?bHDqa_wG6O-1C?|O|{;$-i51C({tHurEE>ven zrca>GpIiLO^o_9%m8WaEXZl5?zU#A5XP;0n@B@|5V^N_b3||7yqbnBQw0OhVgf=xd z$bT|*F4K$VaZ)=P5A#mKJZRfDw*grUnb%I{38brNfr{>*9f)W2Vc=Kn2OuP`R#E<^~ {% trans "URL Manager" %}
+ {% trans "Advanced Search" %}
diff --git a/url_manager/__pycache__/settings.cpython-312.pyc b/url_manager/__pycache__/settings.cpython-312.pyc index 2807626b460b5a8440f7d4c2413f0649379e14ad..d75bd7bf0a53d5440e2c298250b8c409a866f6e1 100644 GIT binary patch delta 80 zcmbO!xImEiG%qg~0}uq)-c5Tjkynz@V50h7j#SPRfhukWhKy-0DV0cEdT%j delta 73 zcmZ1=I8%`KG%qg~0}yO4yqmURBCjN))#LN2F?!xljS)Y0S`eG-T(jq diff --git a/url_manager/settings.py b/url_manager/settings.py index 578ca23..0e168c6 100644 --- a/url_manager/settings.py +++ b/url_manager/settings.py @@ -58,7 +58,8 @@ ALLOWED_HOSTS = [] DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': '/app/data/db.sqlite3', # Updated path + # 'NAME': '/app/data/db.sqlite3', # Updated path + 'NAME': BASE_DIR / 'data/db.sqlite3', } }