URL 中包含类别时的 Django urlpatterns

Django urlpatterns when a category is included into URL

Django 3.0.6

urlpatterns = [
    path('', HomeView.as_view(), name='home'),
    path('{}'.format("admin/" if DEBUG else "dhjfsljdasdhje32/"), admin.site.urls), # Change admin url for security reasons.
    path('image/', include(('image.urls', 'image'), namespace="image")),
    path('polls/', include(('polls.urls', 'polls'), namespace="polls")),
    path('applications/', include(('applications.urls', 'applications'), namespace="applications")),
]

def _get_categories_url_pattern():
    """
    Organize urls with posts categories.
    URL format:
    <category>/<post_slug>
    Example: linux/how_to_install_ubuntu/
    """
    categories = Category.objects.all().values_list("slug", flat=True)
    for category in categories:
        urlpatterns.append(path('{}/'.format(category), include('post.urls')))
        urlpatterns.append(path('draft/{}/'.format(category), include('post.urls')))

_get_categories_url_pattern()

请注意如何处理 url 中的类别。

此代码有问题:

  1. 管理站点添加新分类时,Django项目有 重新启动(至少使用内置开发服务器)。

  2. 上次我做 python manage.py makemigrations 时它爆炸了。我 必须注释掉任何与 _get_categories_url_pattern。然后它进行了迁移。现在我不能再重现这个错误了。但是这段代码似乎存在一些危险。

您能否帮助我了解如何重构此代码以使其至少在添加新类别时无需重新启动开发服务器的情况下工作。

服务器启动时加载 url,因此您应避免在那里进行数据库查询。

当您 运行 migrate 用于新数据库时,您的代码将给出错误,因为类别 table 尚未创建。完成第一次迁移后,代码将 运行 没有错误,但正如您所注意到的,URL 不会随着新类别的添加而更新。

通常的方法是在 URL 模式中添加一个 slug kwarg。

path('applications/', include(('applications.urls', 'applications'), namespace="applications")),
path('<slug:slug>', include('post.urls')),
path('draft/<slug:slug>', include('post.urls')),

然后在视图中,使用get_object_or_404确保类别存在。

from django.shortcuts import get_object_or_404

def category_view(request, slug):
    category = get_object_or_404(Category, slug=slug)
    ...

一个问题是 <slug:slug>/ 将匹配其他 URL,例如/image//polls/。在上面的代码中,我通过将 <slug:slug> 放在 URL 模式的底部避免了这个问题。另一种选择是使用 categories/<slug:slug>/ 之类的东西,这样它就不会与其他 URL 相匹配。