Django urls.py: passing dynamic url parameter into include() - django

I found in Django docs (https://docs.djangoproject.com/en/3.0/topics/http/urls/#passing-extra-options-to-include) that I can pass any constant into include() statement. Here in docs' example we are passing blog_id=3.
from django.urls import include, path
urlpatterns = [
path('blog/', include('inner'), {'blog_id': 3}),
]
But what if I want to pass dynamic url parameter into include()? I mean something like this:
from django.urls import include, path
urlpatterns = [
path('blog/<int:blog_id>/', include('inner'), {'blog_id': ???}),
]
Is it possible?

You do not specify the kwargs, so you write:
from django.urls import include, path
urlpatterns = [
# no { 'blog_id': … }
path('blog/<int:blog_id>/', include('inner')),
]
The url parameter will be passed to the kwargs of the included views.
This is to some extent discussed in the documentation on Including other URLconfs where it says:
(…) For example, consider this URLconf:
from django.urls import path
from . import views
urlpatterns = [
path('<page_slug>-<page_id>/history/', views.history),
path('<page_slug>-<page_id>/edit/', views.edit),
path('<page_slug>-<page_id>/discuss/', views.discuss),
path('<page_slug>-<page_id>/permissions/', views.permissions),
]
We can improve this by stating the common path prefix only once and
grouping the suffixes that differ:
from django.urls import include, path
from . import views
urlpatterns = [
path('<page_slug>-<page_id>/', include([
path('history/', views.history),
path('edit/', views.edit),
path('discuss/', views.discuss),
path('permissions/', views.permissions),
])),
]

Related

(Django) include does not import other apps' urls

In my Django project I have 2 apps: core and books. In my core/urls.py, I use python include('books.url') to import the urls from books/urls.py, but I keep getting this error
I have been having this issue now that's bugging me. I had a workaround for it, though I really want to fix this.
core/urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
# local
urlpatterns = [
path('/', include('books.urls')),
path('admin/', admin.site.urls),
]
books/urls.py
from django.contrib import admin
from django.urls import path
# local
from graphene_django.views import GraphQLView
from books.schema import schema
urlpatterns = [
path('graphql/', GraphQLView.as_view(graphiql=True, schema=schema)),
]
As suggested by SO, I have:
put books.urls inside the single quotes ' '
placed the path('/', include('books.urls')) on top
switch from from django.urls import include to
from django.conf.urls import include
The only workaround I have is place all urls into the core/urls.py, but that seems too chunky in the long run. I don't get why include works for everyone but not me!
Could you help me with this issue? Thank you!
Now GraphQLView is called with the URL 127.0.0.1:8000/graphql/, if you want to call it with the URL 127.0.0.1:8000/, you need to change your code:
core/urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
# local
urlpatterns = [
path('/', include('books.urls')),
path('admin/', admin.site.urls),
]
books/urls.py
from django.contrib import admin
from django.urls import path
# local
from graphene_django.views import GraphQLView
from books.schema import schema
urlpatterns = [
path('/', GraphQLView.as_view(graphiql=True, schema=schema)),
]

Add internationalization to Django URL with prefix of the language coming after the added prefix

I know how to add a general prefix to all urls thanks to this answer https://stackoverflow.com/a/54364454/2219080. But I want to have urls where we have the added prefix always coming before the language prefix (added by i18n_patterns ).
from django.urls import include, path, re_path
from django.views.generic import TemplateView
from django.conf.urls.i18n import i18n_patterns
urlpatterns = [
path("grappelli/", include("grappelli.urls")), # grappelli URLS
path("admin/doc/", include("django.contrib.admindocs.urls")),
path("admin/", admin.site.urls),
path("pages/", include("django.contrib.flatpages.urls")),
re_path(r"^api-auth/", include("rest_framework.urls")),
re_path(r"^accounts/", include("allauth.urls")),
re_path(r"^indicators/", include("indicators.urls", namespace="indicators")),
path("", TemplateView.as_view(template_name="landing.html"), name="landing"),
]
if settings.URL_PREFIX:
urlpatterns = [path(r"{}".format(settings.URL_PREFIX), include(urlpatterns))]
E.g: Having this code above, I would like to have an url https://example.com/mycuteprefix/en/indicators/ instead of the usual https://example.com/en/mycuteprefix/indicators/.
Whenever I apply internationalization to the first urlpatterns I get an error. For example if I try this one bellow:
urlpatterns = [
path("grappelli/", include("grappelli.urls")), # grappelli URLS
path("admin/doc/", include("django.contrib.admindocs.urls")),
path("admin/", admin.site.urls),
path("pages/", include("django.contrib.flatpages.urls")),
re_path(r"^api-auth/", include("rest_framework.urls")),
re_path(r"^accounts/", include("allauth.urls")),
re_path(r"^indicators/", include("indicators.urls", namespace="indicators")),
]
urlpatterns += i18n_patterns(
path("", TemplateView.as_view(template_name="landing.html"), name="landing"),
)
if settings.URL_PREFIX:
urlpatterns = [path(r"{}".format(settings.URL_PREFIX), include(urlpatterns))]
I have this error:
urlpatterns = [path(r"{}".format(settings.URL_PREFIX), include(urlpatterns))]
File "/home/username/.virtualenvs/roject/lib/python3.5/site-packages/django/urls/conf.py", line 52, in include
'Using i18n_patterns in an included URLconf is not allowed.'
django.core.exceptions.ImproperlyConfigured: Using i18n_patterns in an included URLconf is not allowed.
How to achieve that ?

Specifying a namespace in include() without providing an app_name

models.py
from django.conf.urls import include, url
app_name = "Review"
urlpatterns = [
url(r'^books/', include("Review.urls", namespace='reviews')),
]
Review\urls.py
from django.conf.urls import include, url
from django.contrib import admin
from .views import (
ReviewUpdate,
ReviewDelete,
)
urlpatterns = [
url(r'^reviews/(?P<pk>\d+)/edit/$', ReviewUpdate.as_view(), name='review_update'),
url(r'^reviews/(?P<pk>\d+)/delete/$', ReviewDelete.as_view(), name='review_delete'),
]
I am providing app_name before my urlpatterns. But it's giving me error while running my code. The errors are given below:
File "E:\workspace\python\web\Book_Review_App\Book\urls.py", line 13, in <module>
url(r'^books/', include("Review.urls", namespace='reviews')),
File "E:\workspace\python\web\Book_Review_App\venv\lib\site-packages\django\urls\conf.py", line 39, in include
'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.
Please help.
The app_name needs to be set in your app's urls.py not the main urls.py.
In review.urls.py add the following,
from django.conf.urls import include, url
from django.contrib import admin
from .views import ( ReviewUpdate, ReviewDelete, )
app_name = 'Review'
urlpatterns = [
url(r'^reviews/(?P<pk>\d+)/edit/$', ReviewUpdate.as_view(), name='review_update'),
url(r'^reviews/(?P<pk>\d+)/delete/$', ReviewDelete.as_view(), name='review_delete'),
]
and remove the app_name from the main urls
EDIT: for the admin issue that the op mentioned in the comments,
in the main urls.py
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
]
You need to define app_name in urls.py and pass urlconf_module in tuple . Here is example
app_name = "example"
from typing import NamedTuple
class NamedURL(NamedTuple):
urlconf_module: None
app_name: None
daily_urls = NamedURL(<your custom urls in list>, "example")
urlpatterns = [
...
re_path(r'^daily/', include(daily_urls, namespace='daily')),
]

In django 1.10, how do I handle my urls now that patterns is deprecated?

from django.conf.urls import patterns, include, url
urlpatterns = patterns('',
url(r"^$", home),
url(r"^storefront/", storefront),
url(r"^sell/", get_entry),
.
ImportError: cannot import name patterns
The above is a snippet of my urls.py, is fixing this just a matter of changing my import statement or will I literally need to rewrite my entire urls.py now that the patterns module has been deprecated?
In django 1.10 the urls can be defined in the following way:-
from django.conf.urls import include, url
from django.conf.urls.i18n import i18n_patterns
urlpatterns = i18n_patterns(
url("^admin/", include(admin.site.urls)),
)
if settings.USE_MODELTRANSLATION:
urlpatterns += [
url('^i18n/$', set_language, name='set_language'),
]
urlpatterns += [
url("^", include("your_app.urls")),
]
So you dont have to change all your urls. Just place correctly i.e if you are useing I18N place them with admin in urlpatterns = i18n_patterns section else in another section as in example above replace the name with your_app.urls.

TypeError: view must be a callable or a list/tuple in the case of include()

I am new to django and python. During url mapping to views i am getting following error:
TypeError: view must be a callable or a list/tuple in the case of include().
Urls. py code:-
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^posts/$', "posts.views.post_home"), #posts is module and post_home
] # is a function in view.
views.py code:-
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
#function based views
def post_home(request):
response = "<h1>Success</h1>"
return HttpResponse(response)
Traceback
In 1.10, you can no longer pass import paths to url(), you need to pass the actual view function:
from posts.views import post_home
urlpatterns = [
...
url(r'^posts/$', post_home),
]
Replace your admin url pattern with this
url(r'^admin/', include(admin.site.urls))
So your urls.py becomes :
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^posts/$', "posts.views.post_home"), #posts is module and post_home
]
admin urls are callable by include (before 1.9).
For Django 1.11.2
In the main urls.py write :
from django.conf.urls import include,url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^posts/', include("Post.urls")),
]
And in the appname/urls.py file write:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$',views.post_home),
]
Answer is in project-dir/urls.py
Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
Just to complement the answer from #knbk, we could use the template below:
as is in 1.9:
from django.conf.urls import url, include
urlpatterns = [
url(r'^admin/', admin.site.urls), #it's not allowed to use the include() in the admin.urls
url(r'^posts/$', include(posts.views.post_home),
]
as should be in 1.10:
from your_project_django.your_app_django.view import name_of_your_view
urlpatterns = [
...
url(r'^name_of_the_view/$', name_of_the_view),
]
Remember to create in your_app_django >> views.py the function to render your view.
You need to pass actual view function
from posts.views import post_home
urlpatterns = [
...
url(r'^posts/$', post_home),
]
This works fine!
You can have a read at URL Dispatcher Django
and here Common Reguler Expressions Django URLs