URL-тег шаблона django с пустым аргументом

Я пытаюсь сделать просмотр списка статей моей домашней страницы, который работает двумя способами.
Вот часть моего приложения url.py:

path('article_list/<slug:tag>', views.article_list, name='article_list'),

Я хотел бы, чтобы этот URL-адрес охватывал как все статьи, так и теги, указанные в статье, так как представление отображает все статьи, если slug: tag равен '' .
Вот часть моего view.py:

def article_list(request, tag):
    if tag == '':
        articles = get_list_or_404(Article)
    else:
        articles = get_list_or_404(Article, tags__name__in=[tag], publish=True)

    context = {
        'tag': tag,
        'articles': articles,
    }
    return render(request, 'blog/article-list.html', context)

Все работает отлично, за исключением повторного создания URL-адреса статьи в формате html с тегом шаблона django {% url %} .
Я хочу что-то вроде этого:

href="{% url 'article_list' '' %}"

Как я могу сделать URL с пустым аргументом (в данном случае пустым слагом)?

Всего 1 ответ


Причина, по которой это не работает, заключается в том, что преобразователь пути <slug:…> [Django-doc] соответствует только непустым подпоследовательностям пути. Действительно, класс определяется как [GitHub] :

class SlugConverter(StringConverter):
    regex = '[-a-zA-Z0-9_]+'

Здесь есть два основных варианта: создать два пути (один для тегов, другой без тегов) или реализовать преобразователь путей / использовать регулярное выражение.

Вариант 1: два пути

# app/urls.py

from django.urls import path
from app import views

urlpatterns = [
    path('article_list/', views.article_list, name='article_list', kwargs={'slug': ''}),
    path('article_list/<slug:tag>', views.article_list, name='article_list'),
]

Вариант 2: реализовать преобразователь пути

Возможно, здесь стоит реализовать преобразователь пути самостоятельно:

# app/converters.py

from django.urls.converters import SlugConverter

class EmptyOrSlugConverter(SlugConverter):
    regex = '[-a-zA-Z0-9_]*'

Затем вы можете зарегистрировать это и использовать конвертер пути <emptyorslug:…> :

# app/urls.py

from django.urls import path, register_converter
from app import converters, views

register_converter(converters.EmpotyOrSlug, 'emptyorslug')

urlpatterns = [
    path('article_list/<emptyorslug:tag>', views.article_list, name='article_list'),
]

Обратите внимание, что вы можете немного улучшить читаемость вашего представления с помощью:

def article_list(request, tag):
    if not tag:
        articles = get_list_or_404(Article, tags__slug=tag, publish=True)
    else:
        articles = get_list_or_404(Article)

    context = {
        'tag': tag,
        'articles': articles,
    }
    return render(request, 'blog/article-list.html', context)

Обратите внимание, что вы, вероятно, хотите фильтровать по тегу, а не по name .


Есть идеи?

10000