I need my django application connect two different URLs to the same view. When I use regular expression, the result is different from what I expect:
from django.http import HttpResponse
from django.urls import re_path
def readme(request):
return HttpResponse('My test', content_type='text/plain')
urlpatterns = [
re_path(r'^(readme|help)$', readme),
]
I should render both
to the same view. But I receive the following error when entering the URL in my browser:
Exception Value: readme() takes 1 positional argument but 2 were given
Exception Location: /home/ar/.local/lib/python3.8/site-packages/django/core/handlers/base.py, line 197, in _get_response
191 if response is None:
192 wrapped_callback = self.make_view_atomic(callback)
193 # If it is an asynchronous view, run it in a subthread.
194 if asyncio.iscoroutinefunction(wrapped_callback):
195 wrapped_callback = async_to_sync(wrapped_callback)
196 try:
197 response = wrapped_callback(request, *callback_args, **callback_kwargs)
198 except Exception as e:
199 response = self.process_exception_by_middleware(e, request)
200 if response is None:
201 raise
202
203 # Complain if the view returned None (a common error).
You are working with a capture group and pass this as the first item, so it will pass a string readme
or help
, so you can work with:
def readme(request, ):
# item will be 'readme' or 'help'
return HttpResponse('My test', content_type='text/plain')
urlpatterns = [
re_path(r'^(readme|help)/$', readme),
]
It is however more elegant to define just two paths:
def readme(request): # 🖘 no item
return HttpResponse('My test', content_type='text/plain')
urlpatterns = [
path(, readme),
path(, readme),
]
and while not invalid, usually using two paths to point to the same "resource" is not considered good design. Usually you want that two different paths point to different information.
Or if you want to use it with an optional parameter:
def readme(request, lang):
# …
pass
inner_urls = [path('readme/', readme), path('help/', readme)]
urlpatterns = [
path('/', include(inner_urls), kwargs={'lang': None}),
re_path(r'^(?P<lang>en)/$', include(inner_urls)),
]
This will pass en
to lang
, or None
if it was not "picked".
If you however want to pick a language, you likely want to use i18n_patterns(…)
[Django-doc] , which is Django's internationalization solution for multi-language sites.
As error message says, the view need 2 arguments, but you have declared one. That another argument will be your readme
or help
.
So for solving it, you can use *args
:
def readme(request, *args, **kwargs):
return HttpResponse('My test', content_type='text/plain')
Or if you want the readme
or help
in your view, you can have it as just argument:
def readme(request, selected_url):
return HttpResponse('My test', content_type='text/plain')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.