How to use namespace in django + Problems after this - python

I looked at the official Django documentation(https://docs.djangoproject.com/en/3.2/topics/http/urls/#reversing-namespaced-urls) and the error code and wrote the following. How can I write namespaces to work?
views.py:
from django.urls import path, include
app_name = 'home'
urlpatterns = [
path('math/', include('math_note.urls', namespace='math-note'))
]
templates:
math note
Error when running runserver:
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.
Question:
How can I use the namespace function?
Second question:
Thank you! Well connected via
<a href="{% url 'music:home-page' %}">(to app_name = music)
But when I call the form from the music app and load the url to generate, I get an error. The other URLs didn't have any issues, only this one.
Reverse for 'home-page' not found. 'home-page' is not a valid view function or pattern name.
#music/urls.py
from django.urls import path
from . import views
app_name = 'music'
urlpatterns = [
path('', views.music_home_page, name='home-page'),
path('new/', views.new_song, name='new'),
path('music_player/<int:id>/', views.music_player, name='music-player'),
]
Question:
I solved the previous problem and got the following problem. What is the cause and solution of this?

The namespace kwarg that include accepts is an instance namespace i.e. an instance of an application namespace, you cannot have instance namespaces without having an application namespace which as the error specifies you do by specifying app_name in the included module or by passing a 2-tuple containing the patterns and application namespace to include.
Hence you need to modify math_note.urls and add an app_name variable to it:
app_name = 'math_note'
urlpatterns = [
...
]
Keep your other urls (likely in home.urls?) as it is:
from django.urls import path, include
app_name = 'home'
urlpatterns = [
path('math/', include('math_note.urls', namespace='math-note'))
]

just remove namespace from the path.
including a url does not require to have namespace. having your namespace on your math-notes is enough.

views.py
from django.urls import path, include
app_name = 'home'
urlpatterns = [
path('math/', include('math_note.urls', name='math-note'))
]
Use name instead of namespace

app_name in application url will work as namespace. just remove namespace from include in root project directory.
your urlpatterns should look like:
urlpatterns = [
path('math/', include('math_note.urls'))
]
and define app_name='home' in your application urls.
something like:
`app_name='home'`
urlpatterns = [
path('list/', <your view>, name='app-list'),
]

second question answer.
I have set the navbar so I can't see the exact error code content. When I deleted the navbar, I saw the exact error content, and the cause of the error was the return link.

Related

Django 2 namespace and app_name

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'))),
]

NameError-- name 'logs' is not defined. Django-Python

from django.conf.urls import include, url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^logs/', include(logs.urls)),
]
I have written this code in main/urls.py file
code in logs/urls.py is below:-
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$/', views.index, name='index'),
]
and i am accessing http://localhost:8000/logs
Error:- NameError name 'logs' is not defined
You need to import the module you are actually referencing before adding it to your URLs file.
Assuming logs is in your import path:
import logs
Usually you would use a string with include so that you don’t have to import the module;
url(r'^logs/', include('logs.urls')
Also, you should remove the slash from the end of your regex for the index view. The dollar marks the end of the string, so r'^$/' will never match.
url(r'^$', views.index, name='index'),
Please check the docs. It should help!
include() function takes a list/tuple of url(), path(), re_path() and includes them to django routing system.
It also requires app's name: you can define it in include(("enter here your app's name", app.urls))
or in an app itself, in urls.py at a modular level. app_name = 'enter here your apps'name '
But only include() isn't enough, you have to define it in path() or smth that is used for routing (e.g re_path(), url() (deprecated in django 2.0))
For full details: include() function.
So, the full poiting to app's urls look so:
from django.conf.urls import url, include
from . import views
from . import app
urlpatterns = [
url(r'^', include(("app", app.urls)), name='index'),
]
I recommend you to use path() and re_path() if you use Django 2.0 >
I noticed that you use regex incorrectly little bit
url(r'^$/', views.index, name='index'),
You type $ before /, it's incorrect, $ means the end of expression and must be used in the end of expression.
Unfortunately I can't tell you all the details in the post. You should read Django docs. Go through django tutorial for start.
I'm sure it will help!

What is difference between instance namespace and application namespace in django urls?

I am referring https://www.webforefront.com/django/namedjangourls.html to understand django urlconfs. I have encountered terms instance namespace and application namespace. I know about namespaces in urlsconfs. But I don't know the difference between them.
I referred django docs for it. It mentions that instance and app namespaces, comes into picture, when multiple instances of same app is used in django project.
But still, I am not able to understand it. I have googled out, but couldn't find any help on it.
Thanks in advance.
Think of instance namespace as your nickname and application namespace as your real name.
People can have many nicknames for you, but your real name doesn't change.
Django uses the application namespace (your real name) to reverse urls, cause as an application you should not care how many instance namespaces (nicknames) there are.
But to differentiate between one instance and the next, you will use the instance namespaces (nicknames) in urlconfs.
Let's say your app deals with customers and store employees. Both of these have physical addresses and you might want to use an app that just handles all address information: forms, validation, model structure, geo location etc. Our fictional app is a reusable django app called "django_super_address".
Your root url conf may look like this:
urlpatterns = [
path('customer/address/',
include('django_super_address.urls',
namespace='customer_address')
),
path('employee/address/',
include('django_super_address.urls',
namespace='employee_address')
),
]
This includes the same urls below different URL paths, pointing to the same app, using different namespaces (nicknames).
Within django_super_address, it has defined it's application namespace:
# File: django_super_address/urls.py
from . import views
app_name = 'django_super_address'
urlpatterns = [
path('create/', views.SomeAddressCreateView.as_view(),
name='address_create'),
path('create/success/', views.SuccessView(),
name='address_create_success'),
...
]
And in views it uses:
# File django_super_address/views.py
class SomeAddressCreateView(generic.CreateView):
def success_url(self):
return reverse(
'django_super_address:address_create_success'
)
...
When Django gets the URL `/employee/address/create/':
It sets the instance namespace to employee_address
It reads the urls from django_super_address
It sets the application namespace to django_super_address and
associates the urls.py with that application namespace.
In the view:
It reverses the URL by looking at the urls file associated with the application namespace (real name) and reverses the name into: create/success
It then goes back up the chain, now using the instance namespace (nickname) to prepend the rest of the url: root + employee/address/ + create/success/ = /employee/address/create/success/
And there you have it: nicknames for urlconfs and application namespaces for reverse!
From my understanding, it goes like this:
For two different applications using the same URL pattern, use an Application namespace.
For two different instances of the same application using the same URL configuration and views, use an Instance namespace.
The application of Instance namespace might sound a bit confusing. Let me try to clarify if that's the case. Consider the example given in the Django docs.
urls.py:
from django.urls import include, path
urlpatterns = [
path('author-polls/', include('polls.urls', namespace='author-polls')),
path('publisher-polls/', include('polls.urls', namespace='publisher-polls')),
]
polls/urls.py:
from django.urls import path
from . import views
app_name = 'polls'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
...
]
The namespaces are defined like this:
The Application namespace is defined by app_name attribute in polls/urls.py
The Instance namespace is defined by namespace argument in urls.py
Here, both author-polls and publisher-polls are using the same polls.urls to resolve their URLs. Without an Instance namespace, resolving a URL like 'polls:index' could create confusion on which URL it's intending to fetch. That's why Django has a set of protocol defined to fix this issue for all kinds of situations when you are attempting to reverse and resolve namespaced URLs.
You can use the urls.py for an app by including it in different urls path, for example we can have:
urlpatterns = [
path('author-polls/', include('polls.urls')),
path('publisher-polls/', include('polls.urls')),
]
As you see, both included polls.urls which is:
app_name = 'polls' urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('<int:pk>/', views.DetailView.as_view(), name='detail'),
...
]
So far so good!
But there is a problem. In the template, where is 'polls:index' pointing?!
And now instance namespace comes into the picture.
urlpatterns = [
path('author-polls/', include('polls.urls', namespace='author-polls')),
path('publisher-polls/', include('polls.urls', namespace='publisher-polls')),
]
Django has some rules to reverse namespace urls >> https://docs.djangoproject.com/en/3.0/topics/http/urls/#reversing-namespaced-urls
basically each application namespace can have multiple instance namespace ,
for example :
this is project URLs file (main urls) :
path('', include("movie_app.urls")),
path('my_namespace1/', include("movie_app.urls", namespace='my_namespace1')),
path('my_namespace2/', include("movie_app.urls", namespace='my_namespace2')),
you can see, they all mentions to the same app.urls file (movie_app.urls) , but the path link are different .
first one is : "",
and second one is : "my_namespace1/",
and the third is : "my_namespace2/",
and this is movie_app.urls file (child file ) :
app_name = 'movie_app'
urlpatterns = [
path('appmovie1/', myview1 , name="myname"),
]
now when you use the all paths in your html templates for example :
<h1> application namespace : url name</h1>
<h1>instance namespace1 : url name</h1>
<h1>instance namespace2 : url name </h1>
you will note the different in href link :
<h1> application namespace : url name</h1>
<h1>instance namespace1 : url name</h1>
<h1>instance namespace2 : url name </h1>
in the end:
app namespace and instance name space will help you to determine / select the correct URL path from multiple URL paths that use same include .urls file.
I hope this helpful for you .
The namespace instance can only be used with include. This is useful when we want to have multiple paths with different URLs, but we want to include the same URLconf modules.
Let's say we have this code:
#my_site/urls.py
urlpatterns = [
path('url1/',include('english.urls')),
path('url2/',include('english.urls'))]
#english/urls.py
app_name='english'
urlpatterns = [
path('words/', views.index, name='words')]
#template.html
Something
Clicking on the link will redirect us to url1/words, because Django will choose the first element from the urlpatterns. If we want to be redirected to url2/words, we must use the namespace (instance namespace), that is:
#my_site/urls.py
urlpatterns = [
path('url1/',include('english.urls', namespace='eng')),
path('url2/',include('english.urls', namespace='eng2'))]
#english/urls.py
app_name='english'
urlpatterns = [
path('words/', views.index, name='words')]
and then:
#template.html
Something
I will add that if we do not have an instance namespace, Django will probably warn us:
WARNINGS: ?: (urls.W005) URL namespace 'english' isn't unique. You may
not be able to reverse all URLs in this namespace
In general, the instance namespace is useful when, for example:
we want to have different URLs depending on the user's native language, such as: 'django/documentation/', 'django/dokumentacja/' or 'django/en', 'django/pl'
we want to separate URLs for specific groups of people: 'amazon/clients/', 'amazon/employees'
we have changed the URL of the website and to not confuse old users, we also allow access to the site via the previous link
we make it easier to find our site on the internet
This is not limited to different URLs. Even though we use the same views, we can slightly modify them depending on the URL we are on:
def index(request):
current_url = request.path
if current_url == '/url1/words/':
''' do something '''
elif current_url == '/url2/words/':
''' do something else '''
return render(request, 'template.html')
We can, for example, change the context or choose a different template.

Password_reset_done error when attempting to create reset password authentication

I want to allow the user to reset password when the user is signed out and cannot remember the password.
I am using the django authentication framework and have created the reset_password and password_reset_done mappers.
Issue : Though I have created the password_reset_done function I continue to get the below error. Is there a step that I missed that is causing this error? I do not know what I have done wrong.
I have posted all the code that I think is relevant to what I attempting to do.
Edit with full TraceBack:
Here is the code :
relative urls.py
from django.conf.urls import url
from . import views
from django.contrib.auth.views import login, logout, password_reset, password_reset_done
urlpatterns = [
url(r'^$', views.vedic_view, name = 'vedic_home_view'),
url(r'^login/$', login, {'template_name' : 'exist/login.html'}, name = 'login'),
url(r'^logout/$', logout, {'template_name' : 'exist/logout.html'}, name = 'logout'),
url(r'^register/$', views.register_view, name = 'register'),
url(r'^profile/$', views.view_profile, name = 'view_profile'),
url(r'^profile/edit/$', views.edit_profile, name = 'edit_profile'),
url(r'^change-password/$', views.change_password, name = 'change_password'),
url(r'^reset-password/$', password_reset, name = 'reset_password'),
url(r'^reset-password/done/$', password_reset_done, name = 'password_reset_done')
]
main urls.py
from django.conf.urls import url
from django.contrib import admin
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^admin/', admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
from django.conf.urls import include
from django.views.generic import RedirectView
urlpatterns += [
url(r'^exist/', include('exist.urls', namespace = 'exist')),
url(r'^$', RedirectView.as_view(url='/exist/', permanent=True)),
]
password_reset_done is within the exists namespace. It looks like you are trying to reverse the named URL without including the namespace argument somewhere. We would need to see your full traceback to see exactly where that is happening.
Since you are using the built-in auth views, the easiest fix would probably be to move your password reset handling up to your main urls.py. Notice in your traceback that the built-in password_reset view does this:
post_reset_redirect = reverse('password_reset_done')
The default implementation here is to reverse to password_reset_done without any namespace. Moving the relevant URLs up to your main urls.py will allow them to be accessed via reverse without a namespace argument, making the built-in views happy.
I realize what the issue is.
For the built-in reset view there is a post_reset_redirect variable that uses the default implementation reverse(password_reset_done) to go to the password_reset_done view.
The issue is that in my main urls.py document I created the namespace variable
namespace = exist
However I did not override the default post_reset_redirect implementation
from reverse(password_reset_done) to reverse(exist:password_reset_done).
So my current
url(r'^reset-password/$', password_reset, name = 'reset_password'),
should now look like
url(r'^reset-password/$', { 'post_reset_redirect':
'exist:password_reset_done'}, password_reset, name =
'reset_password')
As I see, you didn't include relative.url in your main urls.
EDIT
in relative urls
app_name='exists' #with this name you can call in main urls
urlpatterns = [
url(r'^$', views.vedic_view, name = 'vedic_home_view'),
#...
In main url:
urlpatterns = [
url(r'^exists/', include('exists.urls')),
#...
EDIT 2
Here'sthe docs on the subject, it explains it better than me with examples.

Django apps resolving to the wrong namespace

In my project I have three apps, "abc", "xyz" and "common." Common isn't a real app inasmuch as it just stores templates, models and views that are inherited and extended by both apps.
Project-level urls.py looks like so, and properly redirects requests to the respective app:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^abc/', include('abc.urls')),
url(r'^xyz/', include('xyz.urls')),
]
Both apps' url.py files look like so; the ONLY difference is replace every instance of ABC with XYZ:
from django.conf.urls import url
from views import ABCAlertList as AlertList
from views import ABCEventList as EventList
from views import ABCEventDetail as EventDetail
from views import ABCEventReplay as EventReplay
from views import ABCUploadView as UploadView
urlpatterns = [
url(r'^$', AlertList.as_view(), name='view_alerts'),
url(r'^entities/(?P<uid>\w+)/$', EventList.as_view(), name='view_uid'),
url(r'^entities/(?P<uid>\w+)/replay/$', EventReplay.as_view(), name='view_replay'),
url(r'^entities/(?P<uid>\w+)/event/(?P<eid>\w+)/$', EventDetail.as_view(), name='view_event'),
url(r'^upload/$', UploadView.as_view(), name='upload_file'),
]
Again, all the views are common between both apps so there is nothing app-specific to either of them. Both apps make use of the same line in the same common template:
<a href="{% url 'view_uid' alert.uid %}">
Now, the problem:
App ABC works fine on the top-level page. But the urls it's rendering to go past that point point to the wrong app.
For example, I'll be in
http://localhost:8888/abc/
and the urls on that page render as
http://localhost:8888/xyz/entities/262b3bce18e71c5459a41e1e6d52a946ab47e88f/
What gives? It looks like Django is reading the wrong app's urls.py.
Django can't tell the difference between the URLs under abc/ and xyz/ just by the view name and arguments. Since reversing will go through the patterns in reverse order, the patterns under xyz/ will always match first, so all links generated using reverse() or the {% url %} tag will point to the xyz app.
You need to give each pattern a unique name, or use a URL namespace. In Django 1.9+ you should set the app_name attribute:
app_name = 'abc'
urlpatterns = [
url(r'^$', AlertList.as_view(), name='view_alerts'),
url(r'^entities/(?P<uid>\w+)/$', EventList.as_view(), name='view_uid'),
url(r'^entities/(?P<uid>\w+)/replay/$', EventReplay.as_view(), name='view_replay'),
url(r'^entities/(?P<uid>\w+)/event/(?P<eid>\w+)/$', EventDetail.as_view(), name='view_event'),
url(r'^upload/$', UploadView.as_view(), name='upload_file'),
]
In Django 1.8 you need to pass the namespace parameter to include():
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^abc/', include('abc.urls', namespace='abc')),
url(r'^xyz/', include('xyz.urls', namespace='xyz')),
]
You can then reverse the url by passing the proper namespace:
<a href="{% url 'abc:view_uid' alert.uid %}">
If you need to use the same templates or functions for both apps, you need to set the application namespace of both apps to be the same, but use a different instance namespace.
In 1.9+, this means using the same app_name attribute, but passing a different namespace argument:
# myapp/urls.py
app_name = 'common_app_name'
urlpatterns = [
# app urls
]
# myproject/urls.py
urlpatterns = [
url(r'^abc/', include('abc.urls', namespace='abc')),
url(r'^xyz/', include('xyz.urls', namespace='xyz')),
]
In templates, you need to use the application namespace to reverse urls. The current instance namespace is automatically taken into account. In calls to reverse() you need to pass the current namespace:
reverse('common_app_name:view_alerts', current_app=request.resolver_match.namespace)
In Django 1.8 you don't have the app_name attribute, you need to pass it as a parameter to include():
urlpatterns = [
url(r'^abc/', include('abc.urls', namespace='abc', app_name='common_app_name')),
url(r'^xyz/', include('xyz.urls', namespace='xyz', app_name='common_app_name')),
]
Django 1.8 also won't automatically use the current instance namespace in calls to the {% url %} tag. You need to set the request.current_app attribute for that:
def my_view(request):
request.current_app = request.resolver_match.namespace
...

Categories