I want to write a reusable Django application.
I tell my users to add the following to their urls.py
path('slack/', include(('slack_integration.urls', 'slack_integration'), namespace='slack_integration'),
And in my urls.py I want to have a view login_callback.
Now in my view, I need to get a value of slack_integration:login_callback.
I can trust the user that he/she will integrate it with slack_integration prefix and use it. But is this the best practise? Can I somehow get the name of the namespace for the app if user chooses a different name for it?
Thanks a lot!
Using namespace= within urls.py files is no longer supported, as it moves something specific to the Django app outside of the Python package that is the Django app.
The best practice now is to define the app_name within the urls.py file inside the Django app.
The old way: DON'T DO THIS (pre-Django 2.0)
the root urls.py
path('slack/', include(('slack_integration.urls', 'slack_integration'), namespace='slack_integration'),
The new way: DO THIS! (Django 2.0+)
the root urls.py
from django.urls import path, include
urlpatterns = [
path('slack/', include(('slack_integration.urls', 'slack_integration')),
]
slack_integration/urls.py
from django.urls import path
app_name = "slack_integrations"
urlpatterns = [
path('', HomeView.as_view(), name='home'),
]
As you can see, this keeps the namespace for the patterns within the app itself, along with the templates most likely to use it. The days of extra instructions on how to include an app are over! Good luck.
Related
I just created a new app for my django project and have created a urls.py, models.py, views.py, and serializers.py. However, my project is not detecting the URLs in the urls.py file. If I go to a different app in my project and edit the urls.py file, the system detects it. However, it will not detect it in the new one. Here is the urls.py file:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^knorket-kaitongo-integration/$', views.KnorketKaitongoIntegration.as_view(),
name='knorket_kaitongo_integration'),
]
Does anyone know why this wouldn't be detected? It's not showing up on the API screen either.
Django does not autodetect any files
You need to install them using the installed_apps list and register URLs.
In the Root application, you should find a urls.py file, in that file you need to register your URLs.
You need to import application URLs in Root urls.py and add them in something like this.
urlpatterns = [
path('^', include(urls))
]
I have a custom directory for allauth templates. I need some custom urlpatterns as well as I don't want some default views. I wanted to start with glueing in the entire allauth and change things that I need later on.
My main app config/urls.py file
from django.urls import include, path
urlpatterns = [
path("account/", include("users.urls")),
]
Users app:
users/urls.py
app_name = "users"
urlpatterns = [
path("login/", allauth_views.login, name="account_login"),
path("logout/", allauth_views.logout, name="account_logout"),
path("signup/", allauth_views.signup, name="account_signup"),
]
With this basic setup, if I go to /account/login it routes correctly to the desired view, but it is defined in users app with the app_name = "users", therefore, I have to access it in other views with reverse(users:account_login). The problem is that allauth LoginView has this method
def get_context_data(self, **kwargs):
ret = super(LoginView, self).get_context_data(**kwargs)
signup_url = passthrough_next_redirect_url(self.request,
reverse("account_signup"),
self.redirect_field_name)
redirect_field_value = get_request_param(self.request,
self.redirect_field_name)
site = get_current_site(self.request)
ret.update({"signup_url": signup_url,
"site": site,
"redirect_field_name": self.redirect_field_name,
"redirect_field_value": redirect_field_value})
return ret
which does the lookup on reverse("account_signup") but Django gets lost and throws django.urls.exceptions.NoReverseMatch.
Two solutions:
If I set those allauth urlpatterns in my main urls file it works correctly but I want to keep this file small and define allauth urls in my users app.
If I don't define app_name in my users/urls.py it works properly but I want it for other routes. I consider adding app_name to be a good practice. I could have created another app for allauth without an app name but then I'd have users stuff in two apps.
None of these satisfy me.
What I want:
Can I somehow include them without a namespace? I tried path("account/", include("users.urls", namespace=None)) without any luck.
I wasn't thinking... I can keep my custom users urls in users/urls.py with an app name and create another urls file like users/allauth_urls.py in users app and things work correctly.
Then, with
path("account/", include("users.allauth_urls")),
Things work as exepcted.
I'm following a django tutorial that is a little outdated and in the urls.py file of the first app's directory we need to configure where to direct django to for any url starting with 'notes/'.
There are two separate 'apps' inside the project. I'm in the first one, not notes.
This is the code currently. I added include to import statement:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path(url(r’^notes/‘, include('notes.urls'))),
]
Inside the urlpatterns object, on the first line, path('admin/', admin.site.urls), comes predefined, but I need to add a redirect such that django goes to a different app, called 'notes' and searches there for its entry point, since all of the urls will begin with ‘notes/’.
The tutorial says to use a regular expression and uses this code:
url(r’^notes/‘, include(notes.urls))
so that any url that starts with 'notes/' should be redirected to this other file notes.urls.
However the predefined ones that currently come out of the box with a django project start with path.
I enclosed my notes/n redirect line in path, but not sure if this is correct. Should I instead directly write:
url(r’^notes/‘, include(notes.urls))
Also, do I need to delete the first line provided?
path('admin/', admin.site.urls),
The tutorial has:
urlpatterns = patterns('',
url(r’^notes/‘, include(notes.urls)),
)
and no admin urls line. It's from 2014 I believe.
Simply do:
path('notes/', include('notes.urls'))
I need to include password reset function to my app, but always I have NoReverseMatch error. In addition, I can't view my own templates for password reset process. I created templates in registration folder in the same directory with other templates for my app: myapp/templates/registration
URLS.PY
from django.conf.urls import url, include
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
.....
url(r'^password_reset/$', auth_views.password_reset,
name='password_reset'),
url(r'^password_reset/done/$', auth_views.password_reset_done,
name='password_reset_done'),
url(r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-
9A-Za-z]{1,20})/$',
auth_views.password_reset_confirm, name='password_reset_confirm'),
url(r'^reset/done/$', auth_views.password_reset_complete,
name='password_reset_complete'),
]
I have no custom views for password reset. Should I create views for it? Thanks in advance. Django version 1.11
As for the folder structure, you should follow django docs recommendation, wich states that you should create a subfolder in templates with the name of the app:
Template namespacing
Now we might be able to get away with putting our templates directly
in polls/templates (rather than creating another polls subdirectory),
but it would actually be a bad idea. Django will choose the first
template it finds whose name matches, and if you had a template with
the same name in a different application, Django would be unable to
distinguish between them. We need to be able to point Django at the
right one, and the easiest way to ensure this is by namespacing them.
That is, by putting those templates inside another directory named for
the application itself.
myapp/templates/myapp/registration #if this is a folder you call it in the views as 'myapp/registration/page.html'
As mentioned here,
the include() function allows referencing other URLconfs. Note that the regular expressions for the include() function don't have a $ (end-of-string match character) but rather a trailing slash. Whenever Django encounters include(), it chops off whatever part of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.
The idea behind include() is to make it easy to plug-and-play URLs. Since polls are in their own URLconf (polls/URLs.py), they can be placed under /polls/, or under /fun_polls/, or under /content/polls/, or any other path root, and the app will still work.
Need clarification on second point(above) about, include() is to make it easy to plug-and-play URLs,
For one of the app(webapp) in Django project:
webapp/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
urls.py
views.py
where, root URLconf is pointing to webapp.urls as shown below,
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^webapp/', include('webapp.urls')),
]
here is the complete code
With webapp app, How include() can be used in creating plug and play URLS?
Maybe in a django project, you will register many apps into it, and each will have its own urlconf, at that moment, using the include() will make things simple.
You could just add a prefix for each app and using include() to combine all into root urlConf.
Whenever Django encounters include(), it chops off whatever part of
the URL matched up to that point and sends the remaining string to the
included URLconf for further processing.
The include() works by import_module(), you could refer to this function at this
In Django URLs, include() lets you refer to other app's URLconfs.
It basically means something like this
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^webapp/', include('webapp.urls')),
]
webapp.urls.py
urlpatterns = [
url(r'^$', views.content),
]
Now, whenever you will call /webapp/ it will render the content view.
Plug-and-Play basically means URL /webapp/ is ready to be called. It will return anything that will come under this URL if you have a view specified for this URL.