From 55210ddeb82132d5478e162cb41c90e7c03dc02c Mon Sep 17 00:00:00 2001 From: Junwei Zhao Date: Sat, 2 Nov 2024 22:13:38 +1100 Subject: [PATCH] Add template url --- data/db.sqlite3 | Bin 192512 -> 204800 bytes links/forms.py | 24 ++++++++ .../0008_alter_link_original_url.py | 18 ++++++ links/models.py | 52 +++++++++++++++++- links/templates/links/link_form.html | 8 +++ links/urls.py | 1 + links/views.py | 33 +++++++++-- locale/zh_Hans/LC_MESSAGES/django.mo | Bin 3744 -> 3960 bytes locale/zh_Hans/LC_MESSAGES/django.po | 5 +- new_theme/static/css/dist/styles.css | 15 +++++ 10 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 links/migrations/0008_alter_link_original_url.py diff --git a/data/db.sqlite3 b/data/db.sqlite3 index 60f3aa4c9d05aef6f63669ac7da13dfccf25c90b..a6f7eda27cd66f2dd324d23abf4d46e945442347 100644 GIT binary patch delta 6695 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 DDr3W; delta 3308 zcmYLLdvFuS8Nd5Ze(c@pR>G2uV~A~R2w?C_Hh##)RtyD7f^EPy7{5*@Sr(QhKO_UC z1?&kVw4q>9ylIn`GHudKr%W*>7I_dzCzDK`1AmZYI;Di^ObAWd@H7}GbWhR}&#XtQ z-?!iXzTfv)?K&gx`bs*GZqDa8PG3268R)7XU1aC;$2$+> z;?=bNM4?D&8`BHJNlg#V;ab%lN6t2Ts1? zah;!qU&rG{f*oV!Cp-+c=#fIZp75Z@8Bc*y!>EtWN!_>l;_0>{;P*|lV^BC zjgTdsJd^~rH12>DIVr(YhR3pSF^BKrTljl?8c*P(_z3o44L9R+B+~@x=8y49_@_9G z>+vf5BzE9pdidW8Db9dTk`i=z@wbtrOqj-N=tln&=vqwIBD(Y#_0M^9<>ETL64&4| zT!;PEe+m|0)-iFO<)e_msDklfRKK%3sJI%BSVm<=5mF~lX(sk(@ z=^xT(()-dG>7;Z_`lIw4>7cY1e~!PFc1l~N9!ZrpN_EncQi(KQvPek0FWwL@uU*dDa#1(?G{ID8l{Q_d)E<2S}V#F7bB{LtuVj_7?N znVY@Z=}fkgBm1Egwa-JGHM)KI7;He?Trs|Va16Gg?i|FWM$zGMP|=2LX8heatW~%< zBA240+_0bp$oLINA)Uvmoi__{S9MgBFbj3fV(i~O0Ufw6J-+2sO$!Z?tmo+^z9z^f?$=?VvFkAukETI$k%mG&m>e*W z|IDTS&c6ZH%@rd3^C*qZ2&^%4R>aMY2D9B24EAV#VwQxs*DoWm5j9zu{*IGSXWE{^0@~v8 z2elq@X+D&Z#y2S6!?KWK88*xijNt}FrUV_bRjh;f0G(CVHS&BCFi_Uv@M%xoG-pf)5a-3)Q1{& zlm2X~(b+el0|kunl#}wez$>kknOatIxD_0hJk{?XUL&#NBN?jK7dvix8;)XCj2`E$ zT$SqfhGWEjzlak1wvDC}or0NY6N>vJxu;+~>P(Jm#aqeVQ&h>HBrzqwI|YNrmP8hX zW2lJitcMKpr#wg_{dtfo5Az9#%WyjBb=$~?@4zCGmrpf3p9f3OMg!uo4w2l`u-4om zL@S+II$|9=)&O%-3W_od$}36=D(q!>g(W4$_TnUR$|$6db;3xBx|%lRa92>&{U9qh zvTl%EvV--|X+b2-Dx@9ym+%M06JQF}4GhK%i1ivQOY!zbxzQe6G2rQ=uLf<8OFyS+ z*mVtRk;l(;{`4BOn_7BU!ITWB11@j$BJ!1sY8JW<7P)bAG#cv6J`ltHd>xkH79T5u z(muauE4g%&hM#x?O3hj~>+I!yes!CNp3<>tjh4r=H)sp0UY3QUH=qTzcd@PcCNx`B zPkc^r<-tBrU?3O{F&7yg>SB^QOL4ndgihV4*W>o--Dx9JH=zpoG!|jiEpTDY^@xye zthZ$V5fM;vS9T<#(E4wN8%eTR%^tLj$9RXK>9O;H~viuIrH+FAgKw}^} zY-}XcN7HcP4&*4!Eex~=)Iq{e({cIm4%kueM#N?71A;lh{8o+v8l`AIps?A_kJ)K9?(4T4!^8heOUxn)L9$t6l5j0i|F`r zKgrm)*r5&ioh&o&+QEZbYT_D_f?`;Q8mr^OjqEFiI-_H0{1xMdx5x8zz)thDe>crR zb_r~e`l}eFW^!pa)RHSDFc&vfGCA_S1HpbWUP85O*+UOCErA(WbugtzmV3Ks3+eDL zm%uyb?h2ODIQ`t5xKe1q&+NyF=Q(dW4|@X;d0oIwiL76lvO|<*6hsnsxIGPxBjG9$)^?I zGzE%Sn%cU2ewu(NnNp1I)(O0#=n(6r^QsC9|G~ z9FkE>R!xfG%D23@hq +
+

+ {% trans "Template type allows you to create dynamic URLs with parameters. Use {query, default=value} syntax in the URL." %} +

+

+ {% trans "Example: https://google.com/search?q={query, default=hello}" %} +

+
diff --git a/links/urls.py b/links/urls.py index 44bd7d4..e7d553f 100644 --- a/links/urls.py +++ b/links/urls.py @@ -13,6 +13,7 @@ urlpatterns = [ path('link//edit/', views.LinkUpdateView.as_view(), name='link_update'), path('tools/', views.ToolsView.as_view(), name='tools'), path('/', views.redirect_to_original, name='redirect_to_original'), + path('//', views.redirect_to_original, name='redirect_to_original_with_param'), path('export/', views.export_links, name='export_links'), # New route for link detail view by alias diff --git a/links/views.py b/links/views.py index 4376f45..b115ce2 100644 --- a/links/views.py +++ b/links/views.py @@ -18,6 +18,7 @@ import random from django.utils.text import slugify import markdown import logging +import re logger = logging.getLogger(__name__) @@ -178,16 +179,40 @@ def delete_selected(request): Link.objects.filter(id__in=selected_ids).delete() return redirect('link_list') -def redirect_to_original(request, alias): - # 将别名转换为小写并移除特殊字符 +def redirect_to_original(request, alias, param=None): processed_alias = ''.join(e for e in alias.lower() if e.isalnum()) try: link = Link.objects.get(alias=processed_alias) link.click_count = F('click_count') + 1 link.save() - ClickLog.objects.create(link=link) # 记录点击 - return redirect(link.original_url) + ClickLog.objects.create(link=link) + + try: + # 如果是模板 URL 并且提供了参数 + if param: + # 从 URL 中提取参数名 + pattern = r'\{([^{}]*)\}' + matches = re.finditer(pattern, link.original_url) + for match in matches: + param_str = match.group(1) + if ',' in param_str: + param_name = param_str.split(',')[0].strip() + else: + param_name = param_str.strip() + # 使用提供的参数值 + url = link.get_processed_url(**{param_name: param}) + return redirect(url) + + # 如果没有提供参数,使用默认值 + url = link.get_processed_url() + if url is None: + url = link.original_url + return redirect(url) + except ValueError as e: + messages.error(request, str(e)) + return redirect('link_list') + except Link.DoesNotExist: messages.warning(request, _("The alias '{}' doesn't exist. Do you want to create a new one?").format(processed_alias)) return redirect(reverse('link_create') + f'?alias={processed_alias}') diff --git a/locale/zh_Hans/LC_MESSAGES/django.mo b/locale/zh_Hans/LC_MESSAGES/django.mo index 19ebde9b441ee175c625e559041e5642355f641a..5ef2d4068c8743bde831b8fd23e56182087fbb47 100644 GIT binary patch delta 1253 zcmYk)NlX+$6oBCxW)uP0gS$?dFFKA!D=k}DVRci zb%~o?0@v^ej^a{uFiQ$1p$}J}ETjvU;BAz`4^RpZVJdz^nLml=F^Y*;#3Y$tjFeEN zm`Z(B&W$9xj4V=hq71x+vSoKM2m5dje#Y&%nAPpaTrA+TRiY$*&LmmDAWDA>5952> zgt2U|#Ivzk2Ig@i9?~Aw7NdNU3n&vBv`sqRuKPXOhuWto`CjV&2yUf6f%2jeT#0iD z?7s|5=fdKYf$WybLW$>bIgW==w(ur;@G+jmPspj(^HB7ljRhzR9zc14VU)rl?N@C$ zk^N`a)NcYM7{i|{?xA&q${o$726_Nz5C9ZV* E1*ZzamH+?% delta 1023 zcmYk)Pe@cz6vy#1yk||LGddIf_0OOMO;asiK2i!zA8BHNK5%{0Ou77PWsC)A$LsZyqUS3#fHVn4`ai zRO3*#0kyCdbyXc$!V>o23EYl%u@9%PpV##pRk({yYTSp4_v0W|aVtiie}h^#jWs>Y zdE&D>k9rlqP=x~ChfJaJS&!S@g4>Cz*W>X%+(vu|byJsc6ON(QJ+9~e>0y&3xD9*l zKTP8g@f_+3TUcGjB3AJjs=#yi6<#2Ik2+|XO*&`=)p*c7>Yhiv+Ux1zzlCm*(8h81 z0jj_=q^8B5pYiyE`w{gKe#2g@