ilsurealism
ilsurealism

Reputation: 61

The difference between <str:slug> and <slug:slug> in urls.py of Django application

  1. Why in some cases in urls.py is used str:slug, and in other cases slug:slug? What is the difference? And which option is better to use?
  2. And can I use a category slug and then an article slug in one route?

Upvotes: 2

Views: 1911

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476493

Why in some cases in urls.py is used str:slug, and in other cases slug:slug? What is the difference?

The path converter [Django-doc] is different. Indeed, the <str:slug> will accept a different set of strings (in this case a strict superset) than the strings the <slug:slug> will accept.

The documentation explains what will be matched:

  • str - Matches any non-empty string, excluding the path separator, '/'. This is the default if a converter isn't included in the expression.

  • slug - Matches any slug string consisting of ASCII letters or numbers, plus the hyphen and underscore characters. For example, building-your-1st-django-site.

The str will thus match any non-empty string, it will thus accept 'foo', 'straße', 'foo bar', whereas the slug path convert will only exist as a non-empty sequence of ASCII letters and numbers and hyphens and underscores.

We can also see this in the implementation of the StringConverter [GitHub] and the implementation of the SlugConverter [GitHub]:

class StringConverter:
    regex = '[^/]+'

    def to_python(self, value):
        return value

    def to_url(self, value):
        return value

# ⋮

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

The StringConverter will thus use the [^/]+ regex, whereas the slug converter will match with the [-a-zA-Z0-9_]+ regex.

Usually if you work with slugs, it is better to work with the slug path converter, since this will not match with non-slugs, and usually one matches with slugs, not with strings.

A slug has been introduced to work with a pretty looking URL. A URL where the URL parameter contains a space will be replaced by ugly percentage encoding, so foo%20bar, whereas a slug will normally use a hyphen, so foo-bar.

And can I use a category slug and then an article slug in one route?

Sure you can define a path with:

path('<slug:category_slug>/<slug:article_slug>/', some_view)

The some_view will in that case accept three parameters, so:

def some_view(request, category_slug, article_slug):
    # …
    pass

Upvotes: 5

Related Questions