Django中如何基于条件生成不同URL,避免路径中出现None值
解决方案
该需求完全可以实现,常见有两种实现方案:
方案一:配置多URL规则匹配不同场景(推荐)
这种方式逻辑清晰,可读性高,是Django官方推荐的可选参数处理方式。
- 修改URL配置,新增无parent参数的匹配规则,两条规则共用同一个视图和name:
app_name = 'vineyards' urlpatterns = [ # 匹配无parent参数的路径 path('<str:region>/<slug:slug>/', vineyard_detail, name="detail"), # 匹配带parent参数的路径 path('<str:parent>/<str:region>/<slug:slug>/', vineyard_detail, name="detail"), ]
- 修改视图函数,给parent参数设置默认值为None,原有业务逻辑无需改动:
def vineyard_detail(request, region, slug, parent=None): # 原有业务逻辑保持不变,parent存在时可按需调用 ...
- 修改
get_absolute_url方法,动态拼接参数:
def get_absolute_url(self): kwargs = { 'region': self.region.slug, 'slug': self.slug } # 仅当parent有有效值时才添加到参数中 if self.region.region_parent is not None: kwargs['parent'] = self.region.region_parent return reverse('vineyards:detail', kwargs=kwargs)
方案二:用正则路径匹配可选段
如果不想配置多条URL规则,可以用re_path实现单条路径适配两种场景:
from django.urls import re_path app_name = 'vineyards' urlpatterns = [ # (?:...)为非捕获组,尾部?表示整个parent段可选,匹配时不会占用路径分段 re_path(r'^(?:(?P<parent>[^/]+)/)?(?P<region>[^/]+)/(?P<slug>[-a-zA-Z0-9_]+)/$', vineyard_detail, name="detail"), ]
视图和get_absolute_url的修改逻辑和方案一完全一致。
两种方案都可以自动适配两种路径格式,当parent为None时生成的路径为/你的region值/你的slug值/,parent有值时自动补全前一段,不会出现None出现在路径中的问题。
内容的提问来源于stack exchange,提问作者penk
相关产品推荐
相关产品推荐

