157

After upgrading to Django 4.0, I get the following error when running python manage.py runserver

  ...
  File "/path/to/myproject/myproject/urls.py", line 16, in <module>
    from django.conf.urls import url
ImportError: cannot import name 'url' from 'django.conf.urls' (/path/to/my/venv/lib/python3.9/site-packages/django/conf/urls/__init__.py)

My urls.py is as follows:

from django.conf.urls

from myapp.views import home

urlpatterns = [
    url(r'^$', home, name="home"),
    url(r'^myapp/', include('myapp.urls'),
]
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • My answer is much better than the one selected as correct here, and involves adding a simple wrapper to `urls.py` which makes it an instant fix. Please change your choice of what the best answer is. – John Tate Jul 29 '23 at 11:23
  • @JohnTate I disagree. `path` and `re_path` have been the recommended way since Django 2.0, which is five years old. If you use `url()` in your codebase then it will look more and more outdated over time. I accept that in some cases it might be pragmatic to use an import alias or wrapper function, so if that works for you then go for it, but I’m not going to choose it as the accepted answer here. – Alasdair Jul 29 '23 at 14:05

5 Answers5

250

django.conf.urls.url() was deprecated in Django 3.0, and is removed in Django 4.0+.

The easiest fix is to replace url() with re_path(). re_path uses regexes like url, so you only have to update the import and replace url with re_path.

from django.urls import include, re_path

from myapp.views import home

urlpatterns = [
    re_path(r'^$', home, name='home'),
    re_path(r'^myapp/', include('myapp.urls'),
]

Alternatively, you could switch to using path. path() does not use regexes, so you'll have to update your URL patterns if you switch to path.

from django.urls import include, path

from myapp.views import home

urlpatterns = [
    path('', home, name='home'),
    path('myapp/', include('myapp.urls'),
]

If you have a large project with many URL patterns to update, you may find the django-upgrade library useful to update your urls.py files.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • 5
    This is very important, not least because the latest PyCharm tutorial at Jetbrains still uses django.conf.urls. Especially for newer folks, it's always disconcerting to have code copied from a tutorial breaking on you. – mojado Dec 15 '21 at 17:55
  • Thank you, but I don't know yet why I get `url` from initial template while had installed django4 – user.dz Dec 28 '21 at 11:38
  • 2
    @user.dz the Django 4.0 [template](https://github.com/django/django/blob/stable/4.0.x/django/conf/project_template/project_name/urls.py-tpl) doesn't use `url`. If you end up with `url` in your template then you probably have an earlier version of Django installed. Running `which django-admin` or `django-admin --version` might help you figure out what is going on. Use `python -m django` to ensure you use the correct `django` for your virtual env, e.g. `python -m django startproject myproject`. – Alasdair Dec 28 '21 at 23:13
  • You are right, I was surprised to see `django-admin` version 1.11 inside virtual environment. I make sweep and clean out for the house, found: python 2.7, 3.6, 3.7, 3.8, 3.9, 3.10 in `/usr/local` and another python in `Library` (macos). Mine was installed in `Library`and linked in `/opt` somehow, it was taking the priority. I delete it and start from scratch with correct templates. – user.dz Dec 29 '21 at 17:28
  • I prefer switch to using path it seems more proper... – DragonFire May 31 '22 at 02:26
63

I think a quick fix to this problem is to do followings;

You can easily replace

from django.conf.urls import url

to this:

from django.urls import re_path as url

And keep the rest of code to be same as before. (Thanks @Alasdair)

Hosein Basafa
  • 1,068
  • 8
  • 11
  • 2
    Don't do this: it's unnecessarily verbose. Just change `url()` to `re_path()` at the point where it is used. Or better still start using `path()` for your urlpatterns. – Nitin Nain Aug 03 '22 at 05:50
  • 3
    This is a quick way to fix the error. The disadvantage is that your code will eventually look out of date to other Django developers, and confusing to new Django developers who won’t know what `url()` is. If you’ve got the tune, I recommend switching to `re_path` or `path` as in my answer. – Alasdair Oct 06 '22 at 08:07
2

See in django version 4.0 it will not work. So while installing Django in your Virtual Environment select this version

pip install django==3.2.10

This will definitely solve your error and in main urls.py do this:

from django.conf.urls import url

from django.urls import path,include

davidsbro
  • 2,761
  • 4
  • 23
  • 33
  • 8
    Downgrading to Django 3 is a temporary fix. At some point users should upgrade to Django 4 or later, and at that point you need to replace `url()`s – Alasdair Dec 30 '21 at 10:29
  • 1
    in addition it's probably safer to `pip install 'Django<4.0'` than to pick a pinned version – user5417363 Mar 08 '22 at 06:54
0

I saw this thread, and thought this should just be a wrapper. So I asked a researcher friends GPT-4 bot Aria for this by Telegram, and my faithful servant made me a wrapper. Just put it at the top of your urls.py and things start working again.

def url(regex, view, kwargs=None, name=None):
    return re_path(regex, view, kwargs, name)

Solutions above seem plausible but complicated. If you want an easy fix, this is the one. It works and has restored my blog.

John Tate
  • 780
  • 3
  • 10
  • 23
  • I don’t see the advantage of this. You still need to change wherever you import `url` to use your wrapper, so it would be just as easy to use the `from django.urls import re_path as url` approach if you don’t want to switch to `path` and `re_path`. – Alasdair Jul 27 '23 at 20:16
  • It means that you don't have to change the many instances that call `url` in your `urls.py` to use `re_path` and saves a lot of time. You don't need to import url, you just need this at the top, it uses the `re_path` import and is called `url`. Edit: actually, I kind of see your point here. – John Tate Jul 29 '23 at 11:24
-2

If you are using django-rest-auth or any other package thats causing this error, what you should is to downgrade django.

pip install Django==3.2.19
Code ninja
  • 181
  • 1
  • 5
  • With Python 3.11 this version of Django has issues with collections, a core Python module. Therefore, this is not possible, especially for those of us that have upgraded to Debian Bookworm. – John Tate Jul 29 '23 at 11:22
  • This is a repeat of the suggestion by @davidsbro above – Alasdair Jul 29 '23 at 13:46