Search code examples
djangodjango-urls

Django URL logical OR misunderstood


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

http://127.0.0.1:8000/readme

http://127.0.0.1:8000/help

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).


Solution

  • 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')