django - 自定义 Django SlugField 验证会破坏 URL 匹配
问题描述
我为 URL 中的 slug 编写了一个自定义字段验证器(接受一个模型的 slug 中的句点,SLUG_REGEX = '[-a-zA-Z0-9_.]+$'
):
def validate_my_slug(value):
my_slug_re = re.compile(settings.SLUG_REGEX)
if not my_slug_re.match(value):
raise ValidationError(
_('Slugs must consist of letters, numbers, '
'underscores, hyphens, or periods.'),
params={'value': value},
)
中的字段models.py
:
slug = models.CharField(max_length=64, null=True, blank=True,
validators=[validate_my_slug])
这在 Django admin 中保存模型时有效。但是在我的 URLConf 中,这不再有效(它在更改 slug 验证之前确实有效):
path('product-release/<slug:slug>', ProductReleaseDetail.as_view(),
name='product-detail')
我找到了一个解决方案
re_path
,但我不确定这是正确/最好的方法:re_path('product-release/(?P<slug>[-a-zA-Z0-9_.]+)$', ProductReleaseDetail.as_view(), name='product-release-detail')
现在这不再有效(出现在
re_path
上面的模式之前urls.py
):path('product-releases', ProductReleaseList.as_view(), name='product-release-list')
除了与产品发布列表匹配的内容外,一切正常。当我更改 slug 验证器时,URLhttp://localhost:8080/product-releases
停止工作,并出现错误:
NoReverseMatch at /product-releases
Reverse for 'product-release-detail' with no arguments not found.
1 pattern(s) tried: ['product-release/(?P<slug>[-a-zA-Z0-9_.]+$)']
但这似乎是错误的,因为我什至没有尝试达到product-release-detail
;我试图达到product-release-list
。我一定在这里遗漏了一些简单的东西,但现在我的视野变得模糊了。
views.py
. . .
class ProductReleaseList(ListView):
model = ProductRelease
class ProductReleaseDetail(DetailView):
model = ProductRelease
. . .
urlpatterns
. . .
# Product Releases
path('product-releases', ProductReleaseList.as_view(), name='product-release-list'),
re_path('product-release/(?P<slug>[-a-zA-Z0-9_.]+$)', ProductReleaseDetail.as_view(), name='product-release-detail'),
# Release Notes
path('release-notes', ReleaseNoteList.as_view(), name='release-note-list'),
re_path('release-note/(?P<slug>[-a-zA-Z0-9_.]+$)', ReleaseNoteDetail.as_view(), name='release-note-detail'),
. . .
productrelease_list.html
. . .
<h4><a href="{% url 'product-release-detail' %}">{{ p }}</a></h4>
. . .
解决方案
在您的模板中,您使用的是类似于:
{% url "product-release-detail" varname %}
然而,这个变量显然可以是空的(或者由于拼写错误甚至总是空的)。这样就完成了/<slug:slug>
(我不同意顺便说一句,但这不是重点)。随着您的限制和更好re_path
,现在(正确地)会产生一个错误,因为/product-release/
它不是一个有效的 url:一个 slug 应该至少有一个字符。
所以根本原因是以太,变量命名不正确,或者你有没有蛞蝓的产品(你不应该有)。
地址评论
- 在模板中注释掉是用
{# #}
. 确保您没有使用<!-- -->
,因为它仍然执行代码。 - 就目前而言
{% url "product-release-detail" %}
是无效的:它需要一个论据,即一个蛞蝓。如果要链接到列表视图,请使用{% url "product-release-list" %}
as 可以不带参数调用。 - 我不知道 {{ p }} 是什么,但我假设是产品对象。在这种情况下,您应该使用
{%url "product-release-detail" p.name_of_slug_field %}
.
推荐阅读
- sql - 蜂巢查询中的串联
- javascript - 如何在javascript中使用数组作为对象键?
- reactjs - 在周视图和日视图上反应大日历错误 - 'iteratee 不是函数'
- flutter - 连续显示 ListView 项
- c# - 从 C# 控制台应用程序调用 R 函数
- asp.net-core - IFormFile 在 dotnet 核心上返回空值
- .htaccess - 如何在 .htaccess 中重写网站 URL
- php - 如何在 Laravel Eloquent 中编写一个 DISTINCT 嵌套在 COUNT 中的选择查询?
- c++ - 有没有办法将我的代码转换为循环以提高效率
- php - 在内部联接中使用 JSON 数据进行查询