django тег URL шаблона с пустым аргументом - PullRequest
2 голосов
/ 15 января 2020

Я пытаюсь сделать просмотр списка статей на моей домашней странице, который работает двумя способами.
Вот часть моего приложения 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 template {% url %}.
Я хочу что-то вроде этого:

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

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

1 Ответ

1 голос
/ 15 января 2020

Причина, по которой это не работает, заключается в том, что преобразователь пути <slug:&hellip;> [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'<b>, kwargs={'slug': ''}</b>),
    path('article_list/<slug:tag>', views.article_list, name='article_list'),
]

Опция 2: реализуйте преобразователь пути

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

# app/converters.py

from django.urls.converters import SlugConverter

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

Затем вы можете зарегистрировать его и использовать преобразователь пути <emptyorslug:&hellip;>:

# app/urls.py

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

<b>register_converter(converters.EmpotyOrSlug, 'emptyorslug')</b>

urlpatterns = [
    path('article_list/<<b>emptyorslug:</b>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)

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

...