I have a url path in urls.py:
urlpatterns = [
...
url(r'^accounts/', include('allauth.urls')),
...
]
but the url will show: unresolved reference 'url'. Did I miss something to import?
As of Django 2 url() was replaced with path() and re_path(). If you are not using Django 1, you can update your code to use path().
from django.urls import path, include
urlpatterns = [
path('accounts/', include('allauth.urls')),
]
For matching a path with RegEx like the Django 1 url() function you can use re_path() like this...
from django.urls import path, include
urlpatterns = [
re_path(r'^accounts/', include('allauth.urls')),
]
However, because of how simple the path you are trying to match is, I would recommend using path(). It saves to overhead of performing a regular expression match. Use path() over re_path() as much as possible.
You can read more on the official Django documentation. See links below.
Django 3 Documentation
Old Django 1 Documentation
You may be using Django 2.x
For django-1.x, you can not use such path(..)s, and in that case you need to write a regular expression, like:
url(r'^complete/(?P<todo_id>[0-9]+)$', views.completeTodo, name='complete'),
If you are using django-2.x, you probably want to use path(..), like you have.
I believe it may be to do with how you've set up your regex.
For urls, instead of this:
url('complete/<todo_id>', views.completeTodo, name='complete'),
try this:
url(r'^complete/(?P<todo_id>\d+)$', views.completeTodo, name='complete'),
Or incase you want to use [path]
path('complete/<int:todo_id>', views.completeTodo, name='complete'),
Related
I am having trouble understanding the following warning. I have a namespace called "v1" and I am using these namespaces to determine versioning in my API (using django rest framework). So, I have paths like these:
/v1/accounts/me
/v1/listings
Here is the URLs configuration (project/urls.py):
urlpatterns = [
path('admin/', admin.site.urls),
path('v1/accounts/', include('accounts.urls', namespace='v1')),
path('v1/listings/', include('listings.urls', namespace='v1'))
]
accounts/urls.py
app_name = 'accounts'
urlpatterns = [
url(r'^token/$', views.obtain_auth_token, name='obtain_token'),
url(r'^me/$', my_account, name='my_account'),
]
listings/urls.py
app_name = 'listings'
urlpatterns = [
path('', recent_listings, name='recent_listings')
]
Everything works as expected. All urls are dispatched. Versioning works. However, I keep getting the following error:
?: (urls.W005) URL namespace 'v1' isn't unique. You may not be able to reverse all URLs in this namespace
I know it is a warning and I might be able to suppress it; however, I want to understand why this is happening. Based on my URLconf and this warning, it seems like there cannot be multiple namespaced paths as "siblings." They need to be children of one namespaced path (e.g "v1"). If my understanding is correct, how am I supposed to create this URL configuration.
Basically what happens is that, namespace plays a significant role on reverse finding the url. For example:
In your example reverse('v1:obtain_token') will return /v1/accounts/token/. Lets say you have two urls with same name in accounts and listings, then you might not be able to find accounts url in reverse query. That is why the warning is for. Better if you use different namespaces for each include. In you case, it should be:
path('v1/accounts/', include('accounts.urls', namespace='accounts')),
path('v1/listings/', include('listings.urls', namespace='listings'))
Please read the documentations for more details.
Update
you can do the versioning like this:
path('accounts/', include('accounts.urls', namespace='accounts')), # accounts url
inside accounts app:
path('v1/token/', views.obtain_auth_token, name='obtain_token_v1'),
path('v2/token/', views.obtain_auth_token2, name='obtain_token_v2'),
...
When I try to fix the url in my urlpatterns it shows me this error :
The error:
Your URL pattern "url(r'^player/[?P[-\w\x20]+]/$', PlayerDetailView.as_view(), name='player-detail-view'),"
is invalid. Ensure that urlpatterns is a list of url() instance.
try removing the string 'url(r'^player/[?P[-\w\x20]+]/$', PlayerDetailView.as_view(), name='player-detail-view'),'. The list of urlpatterns should not have a prefix string as the first element.*
My Code :
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', HomePageView.as_view(), name='home-page'),
url(r'^teams/$', TeamsListView.as_view(), name='teams-list-view'),
url(r'^scores/$', ScoresListView.as_view(), name='scores-list-view'),
url(r'^player/[?P<slug>[-\w\x20]+]/$', PlayerDetailView.as_view(), name='player-detail-view'),
]
Can anyone help me??
The syntax is a bit off, you need to use round brackets (..) instead of square brackets [..] around a "capture group":
url(
r'^player/(?P<slug>[-\w\x20]+)/$',
PlayerDetailView.as_view(),
name='player-detail-view'
),
Furthermore if I recall correctly, a slug can not contain spaces, so you might want to remove the \x20.
Note that in django-2.0 and higher, the path(..) [Django-doc] function can be used, which has support for slugs like:
# Django 2.0 and higher
path('player/<slug:slug>/', PlayerDetailView.as_view(), name='player-detail-view'),
Then Django replaces the slug with a builtin pattern, which makes the URL patterns more "declarative".
I have my urls.py included like this:
urlpatterns = [
path('files/', include('files.urls')),
]
then, in files/urls.py, I put this:
urlpatterns = [
path('', views.index, name='index'),
path(r'(?P<name>[a-z]+)', views.check, name='check')
]
So, I assume that when example.com/files works, so should example.com/files/somename, but it doesn't:
Using the URLconf defined in example.urls, Django tried these URL
patterns, in this order:
[name='index']
files/ [name='index']
files/ (?P<name>[a-z]+) [name='check']
The current path, files/somename, didn't match any of these.
What am I missing here?
You don't need to use regexp with path method. Instead you can simply specify str as argument type:
path('<str:name>/', views.check, name='check')
If you want to use regular expression, use re_path:
re_path(r'(?P<name>[a-z]+)', views.check, name='check')
In a django online course, the instructor has us use the url() function to call views and utilize regular expressions in the urlpatterns list. I've seen other examples on youtube of this.
e.g.
from django.contrib import admin
from django.urls import include
from django.conf.urls import url
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^polls/', include('polls.urls')),
]
#and in polls/urls.py
urlpatterns = [
url(r'^$', views.index, name="index"),
]
However, in going through the Django tutorial, they use path() instead e.g.:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name="index"),
]
Furthermore regular expressions don't seem to work with the path() function as using a path(r'^$', views.index, name="index") won't find the mysite.com/polls/ view.
Is using path() without regex matching the proper way going forward? Is url() more powerful but more complicated so they're using path() to start us out with? Or is it a case of different tools for different jobs?
From Django documentation for url
url(regex, view, kwargs=None, name=None) This function
is an alias to django.urls.re_path(). Itβs likely to be deprecated in
a future release.
Key difference between path and re_path is that path uses route without regex
You can use re_path for complex regex calls and use just path for simpler lookups
The new django.urls.path() function allows a simpler, more readable URL routing syntax. For example, this example from previous Django releases:
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive)
could be written as:
path('articles/<int:year>/', views.year_archive)
The django.conf.urls.url() function from previous versions is now available as django.urls.re_path(). The old location remains for backwards compatibility, without an imminent deprecation. The old django.conf.urls.include() function is now importable from django.urls so you can use:
from django.urls import include, path, re_path
in the URLconfs. For further reading django doc
path is simply new in Django 2.0, which was only released a couple of weeks ago. Most tutorials won't have been updated for the new syntax.
It was certainly supposed to be a simpler way of doing things; I wouldn't say that URL is more powerful though, you should be able to express patterns in either format.
Regular expressions don't seem to work with the path() function with the following arguments: path(r'^$', views.index, name="index").
It should be like this: path('', views.index, name="index").
The 1st argument must be blank to enter a regular expression.
Path is a new feature of Django 2.0.
Explained here :
https://docs.djangoproject.com/en/2.0/releases/2.0/#whats-new-2-0
Look like more pythonic way, and enable to not use regular expression in argument you pass to view... you can ue int() function for exemple.
From v2.0 many users are using path, but we can use either path or url.
For example in django 2.1.1
mapping to functions through url can be done as follows
from django.contrib import admin
from django.urls import path
from django.contrib.auth import login
from posts.views import post_home
from django.conf.urls import url
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^posts/$', post_home, name='post_home'),
]
where posts is an application & post_home is a function in views.py
I'm currently using the following urls.py:
api_patterns = [
url(r'^users/', include('users.urls', namespace='user')),
]
internal_patterns = [
# ...
]
urlpatterns = [
url(r'^api/', include(api_patterns)),
url(r'^internal/', include(internal_patterns)),
url(r'^admin/', include(admin.site.urls)),
url(r'^(?!(?:api|internal|admin)/)', MainView.as_view()),
]
The point of this config is to render MainView if url doesn't have the api, internal or admin prefix:
/api/users/... β found
/api/foo/ β not found
/foo/ β found
How can I make it simplier and more intent revealing?
I think your intent will be more clear if you do this in two urls:
url(r'^(api|internal|admin)/', SomeView.as_view()),
url(r'^.*', MainView.as_view())
MainView will be executed only if a url does not begin with api, internal or admin.
SomeView will be executed if a url begins with api/internal/admin but doesn't match the patterns above it. You can customize this view to either return a default 404 page, or perform other functions as you need.
Using your examples:
/api/users will execute include(api_patterns)
/api/foo will execute SomeView
/foo will execute MainView
Edit
To address the first point in your comment: url patterns are regexes, while you can extract these into variables to remove duplication, it can make code hard to read. Here's one example for removing duplication (I'm sure you can come up with others):
d = OrderedDict([
(r'api', api_patterns),
(r'internal', internal_patterns),
(r'admin', admin.site.urls),
])
main_view_re = r'^!({})/'.format('|'.join(d.keys()))
urlpatterns = [url(r'^{}/'.format(k), include(v)) for k, v in d]
urlpatterns.append(url(main_view_re, MainView.as_view()))
For django >= 3 rather use re_path:
from django.urls import re_path
urlpatterns = [
re_path(r'^.*',MainView.as_view())
]
urlpatterns = [
url(r'^api/', include(api_patterns)),
url(r'^internal/', include(internal_patterns)),
url(r'^admin/', include(admin.site.urls)),
url(r'', MainView.as_view()),
]
Leaving no prefix would allow you to catch any URL that a user might try after the URL conf matches the api, internal and admin url's.