I need to check if the request path is outside the i18n_pattern, i.e. it should not have 'lang' prefix. For example, I have the following urls.py:
urlpatterns = [
path('api/', include('api.urls'), name='api'),
]
urlpatterns += i18n_patterns(
path('', include('core.urls'), name='index'),
prefix_default_language=False
)
The reverse for 'api' shows that it will not be prefixed whatever language is used. Are there any other ways to figure out that the path of the current request is not included in i18n_patterns? Thanks!
You can check if url is not in the i18n_pattern using django.urls.LocalePrefixPattern:
from django.urls import LocalePrefixPattern
pattern = LocalePrefixPattern()
def view(request):
if not pattern.match(request.resolver_match.route):
...
Related
So, I am not really lucky with latest django version tutorials, so I've had some problems with things that changed between some versions. One of this things is: althought I do exactly as I read/watch in the tutorials I always get the same result - all urls redirect to the same HTML page.
Here is my root urls.py
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('theblog.urls')),
]
Here is my app urls:
from django.conf.urls import url, include
from .views import HomeView, ArticleDetailView
urlpatterns = [
url('', HomeView.as_view(), name='home'),
url('^article/<int:pk>', ArticleDetailView.as_view(), name='article-detail'),
]
For example, when I go to localhost:8000/articles/1 (or any other pk), it renders home.html (HomeView class) as if it was localhost:8000/.
Hope you can help me. Thanks!
There are two things wrong with your code.
url('^article/<int:pk>', ArticleDetailView.as_view(), name='article-detail'),
This will not work. If you want to use url. you can't use <int:pk>, you need to use a RegEx:
url("article/([0-9]+)/", ArticleDetailView.as_view(), name="article-detail")
Note that this will be deprecated in the future and if you are using django >=2.0 you should use path:
path("article/<int:article>/", ArticleDetailView.as_view(), name="article-detail")
However this will still direct you to the wrong view. django stops after the first URL pattern match.
Switch them around to fix that:
urlpatterns = [
url("article/([0-9]+)/", ArticleDetailView.as_view(), name="article-detail"),
# path("article/<int:article>/", ArticleDetailView.as_view(), name="article-detail"), # alternative with path instead of url
url('', HomeView.as_view(), name='home')
]
It may be due to this line
url('', HomeView.as_view(), name='home'),
Because url wraps re_path there may be some logic which will treat the blank regex string as a wildcard. Try changing it to '/'
url('/', HomeView.as_view(), name='home'),
I have the following urls.py in my project dir,
Main project urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.render_calculator, name='render_calculator'),
path('calculator/', views.render_calculator, name='render_calculator'),
path('disclaimer/', views.render_disclaimer, name='render_disclaimer'),
path('cookiepolicy/', views.render_cookiepolicy, name='render_cookiepolicy'),
path('privacypolicy/', views.render_privacypolicy, name='render_privacypolicy'),
path('dashboard/', views.render_dashboard, name='render_dashboard'),
path('about/', views.render_about, name='render_about'),
path('admin/', admin.site.urls),
path(r'^', include('accounts.urls'))
]
Now I created a new app accounts (I added it to my apps in settings.py) where I would like to store the urls of that app in its own dir like so:
Accounts app urls.py
from . import views
from django.urls import path
urlpatterns = [
path('register/', views.render_register, name='render_register'),
]
Accounts app views.py:
from django.shortcuts import render
def render_register(request, template="register.html"):
return render(request, template)
However, this configuration throws me this error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/register
Using the URLconf defined in CFD.urls, Django tried these URL patterns, in this order:
[name='render_calculator']
calculator/ [name='render_calculator']
disclaimer/ [name='render_disclaimer']
cookiepolicy/ [name='render_cookiepolicy']
privacypolicy/ [name='render_privacypolicy']
dashboard/ [name='render_dashboard']
about/ [name='render_about']
admin/
^
The current path, register, didn't match any of these.
Where is the missing piece?
You are using path() with the regex r'^' which is causing your problem.
In order to define a path with a regex, you need to use re_path.
So change it to the following line:
re_path(r'^', include('accounts.urls'))
or you can use
path('', include('accounts.urls'))
Change this.
path(r'^', include('accounts.urls')) to
path('', include('accounts.urls'))
I am having a difficult time understanding the connection between app_name and namespace.
consider the project level urls.py
from django.urls import path, include
urlpatterns = [
path('blog/', include('blog.urls', namespace='blog')),
]
consider the app level (blog) urls.py
from django.urls import path
from . import views
app_name = 'blog'
urlpatterns = [
path('', views.post_list, name='post_list'),
path('<int:year>/<int:month>/<int:day>/<slug:post>/', views.post_detail, name='post_detail'),
]
if I comment out app_name, I get the following.
'Specifying a namespace in include() without providing an app_name '
django.core.exceptions.ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in
the included module, or pass a 2-tuple containing the list of patterns and app_name instead.
If I rename app_name to some arbitrary string, I don't get an error.
app_name = 'x'
I've read the documentation but its still not clicking. Can someone tell me how/why app_name and namespace are connected and why are they allowed to have different string values? Isn't manually setting app_name redundant?
try removing app_name='blog'
In your case you should be using:
'blog:post_list'
and
'blog:post_detail'
You can also remove the namespace='blog' in your first url like so:
urlpatterns = [
path('blog/', include('blog.urls')),
]
and then in your templates you can reference the urls without the 'blog:.....':
'post_list'
'post_detail'
try using tuple.
urlpatterns = [
path('blog/', include(('blog.urls', 'blog'))),
]
This should be an easy enough problem to solve for you guys:
I just started working with Django, and I'm doing some routing. This is my urls.py in the root of the project:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('dashboard.urls')),
]
This is the routing in my dashboard app:
urlpatterns = [
path('dashboard', views.index, name='index'),
path('', views.index, name='index'),
]
Now let's say I want my users to be redirected to /dashboard if they go to the root of the website. So I would use '' as a route in the urls.py in the root, and then have everyone sent to /dashboard from the urls.py in the dashboard app. But when I do this I get the following warning:
?: (urls.W002) Your URL pattern '/dashboard' [name='index'] has a route beginning with a '/'. Remove this slash as it is unnecessary. If this pattern is targeted in an include(), ensure the include() pattern has a trailing '/'.
So I tried to use '/' instead of '', but since a trailing / is automatically removed from an url, the url wouldn't match the pattern. Should I ignore/mute this warning or is there another way to go about it?
This is the code that worked perfectly but gave me a warning earlier:
urlpatterns = [
path('/dashboard', views.index, name='index'),
path('', views.index, name='index'),
]
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('dashboard.urls'))
]
You can use RedirectView to redirect from / to /dashboard/. Then use 'dashboard' when including the dashboard urls.
urlpatterns = [
path('admin/', admin.site.urls),
path('', RedirectView.as_view(pattern_name='dashboard:index')
path('dashboard/', include('dashboard.urls')),
]
You can then remove 'dashboard' from the path in dashboard/urls.py, as it is already in the include().
app_name = 'dashboard'
urlpatterns = [
path('', views.index, name='index'),
]
I've added app_name='dashboard' to match the namespace used above in pattern_name='dashboard:index'.
Note that Django projects usually use URLs with a trailing slash, e.g. /dashboard/ instead of dashboard.
If you really want to use URLs like /dashboard without a trailing slash, then the include should be
path('dashboard', include('dashboard.urls')),
If you do this, I suggest you set APPEND_SLASH to False in your settings.
You can try something like this:
from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from django.views.generic import RedirectView
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^contacts/', include('appname.contacts.urls')),
url(r'^comments/', include('appname.urls')),
url(r'^subscriptions/', include('appname.partner.urls')),
url(r'^', RedirectView.as_view(url="/admin/"))
]
This is what I've done in my project so whenever the user go to 127.0.0.1:8000 it redirects to /admin
I am using djangos include feature in my main urls file, from my app urls file.
main urls.py
from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^posts/', include('posts.urls')),
]
posts.urls.py
from django.conf.urls import url
from . import views #relative import to post views
urlpatterns = [
url(r'$',"views.posts_list" ), #list all posts
url(r'create/$',"views.posts_create" ),
url(r'detail/$',"views.posts_detail" ),
url(r'update/$',"views.posts_update" ),
url(r'delete/$',"views.posts_delete" ),
]
here is the error:
raise TypeError('view must be a callable or a list/tuple in the case of include().')
TypeError: view must be a callable or a list/tuple in the case of include().
I have looked at the docs on this issue:
https://docs.djangoproject.com/en/1.11/ref/urls/#include
and the source code:
https://docs.djangoproject.com/en/1.11/_modules/django/conf/urls/#include
and I have no idea what I am doing wrong.
Please help. Hugs kisses, and high fives
Django 1.10+ no longer allows you to specify views as a string (e.g. 'myapp.views.index') in your URL patterns.
So you should config your posts urls.py like this:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.posts_list, name='list'),
url(r'^create/$', views.posts_create, name='create'),
url(r'^detail/$', views.posts_detail, name='detail'),
url(r'^update/$', views.posts_update, name='update'),
url(r'^delete/$', views.posts_delete, name='delete'),
]
It is also a good practice to add name to your urls.