In Django <2 the normal way of doing this is to use regex expression. But it is now recommended in Django => 2 to use path() instead of url()
path('account/<int:code>/', views.account_code, name='account-code')
This looks okay and works well matching url pattern
/account/23/
/account/3000/
However, this issue is that I also want this to match negative integer like
/account/-23/
Please how do I do this using path()?
You can write custom path converter:
class NegativeIntConverter:
regex = '-?\d+'
def to_python(self, value):
return int(value)
def to_url(self, value):
return '%d' % value
In urls.py:
from django.urls import register_converter, path
from . import converters, views
register_converter(converters.NegativeIntConverter, 'negint')
urlpatterns = [
path('account/<negint:code>/', views.account_code),
...
]
I'm too lazy to make a fancy path converter, so I just captured it as a string and cast it to an integer in the view (with some basic sanity checking to make sure the value can be properly cast to an integer):
urlpatterns = [
path('account/<str:code>/', views.account_code),
...
]
Function-Based View (FBV) example:
from django.http import HttpResponseNotFound
def your_view(request, code):
try:
code = int(self.kwargs['code'])
except ValueError:
# produces HTTP status code 404: Not Found
return HttpResponseNotFound(
"'code' must be convertible to an integer.")
Class-Based View (CBV) example:
from django.http import HttpResponseNotFound
from django.views.generic import TemplateView
class CodeView(TemplateView):
def dispatch(self, request, *args, **kwargs):
try:
code = int(self.kwargs['code'])
except ValueError:
# produces HTTP status code 404: Not Found
return HttpResponseNotFound(
"'code' must be convertible to an integer.")
return super().dispatch(request, *args, **kwargs)
If you wanted the user to know that a client-side error occurred, you could substitute HttpResponseNotFound with HttpResponseBadRequest, which would give an HTTP status code 400 (Bad Request)
EDIT: The version below produces a server error HTTP response code and is probably not desirable (may show up in error logs, etc.)
try:
code = int(self.kwargs['code'])
except ValueError:
# produces HTTP status code 500: Internal Server Error
raise ValueError("'code' must be convertible to an integer.")