Reputation: 344
I'm modelling genome assemblies whose names often contain a dot (.) I wrote a DetailView which works for names without dots but noth names with dots. I get this error:
404 - Using the URLconf defined in genomeDBmanager.urls, Django tried these URL patterns, in this order: ...
My model:
class Assembly(models.Model):
...
identifier = models.SlugField('unique identifier', max_length=50, unique=True)
...
My view.py:
class AssemblyDetailView(DetailView):
slug_field = 'identifier'
template_name = 'overview/assembly.html'
model = Assembly
context_object_name = 'assembly'
My overview/urls.py:
app_name = 'overview'
urlpatterns = [
...
path('assembly/<slug>/', views.AssemblyDetailView.as_view(), name='assembly-detail')
]
This URL works: 127.0.0.1:8000/strain/SomeAssembly-1
, this one doesn't: 127.0.0.1:8000/strain/SomeAssembly.2
.
Upvotes: 1
Views: 1449
Reputation: 476659
Short answer: this is correct behavior for a slug, since a slug is not supposed to have dots.
A slug simply does not allow dots in the slug. Indeed, if we slugify(..)
[Django-doc] for example 'foo.bar'
, we get:
>>> from django.utils.text import slugify
>>> slugify('foo.bar')
'foobar'
It is therefore absolutely valid to not accept dots. It thus means that the SlugField
of your model, likely does not slugify the title (or whatever is "slugified") correctly.
You can accept str
ings, and path
s with the str
and path
path converters, as is specified in the documentation on path converters [Django-doc]:
str
- Matches any non-empty string, excluding the path separator,'/'
. This is the default if a converter isn’t included in the expression.(..)
path
- Matches any non-empty string, including the path separator,'/'
. This allows you to match against a complete URL path rather than just a segment of a URL path as withstr
.
So you can specify for example:
path('assembly/<str:slug>/', views.AssemblyDetailView.as_view(), name='assembly-detail')
but again, this is not a slug.
Upvotes: 4
Reputation: 344
The problem was that the default slug-regex doesn't accept dots. The solution is to specify one using re_path like this:
re_path(r'^assembly/(?P<slug>[0-9a-zA-Z.\-_ ]+)/$', views.AssemblyDetailView.as_view(), name='assembly-detail')
Everything else works the same.
Upvotes: 1