Django Reverse the mapper, URL name doesn't work - python

I'm currently doing on Django project and using reversing the mapper on urls.py. Before I use reversing it worked well, but after I change it to reversing, it started to do not work anymore.
I want to know why it doesn't work. Is it because I didn't add it in proejct file's urls.py? How can I call that url with the name in app's file?
from django.urls import path
from . import views
app_name = 'posting'
urlpatterns = [
path('', views.index, name='index'),
path('<int:post_id>', views.post, name='post'),
path('posting', views.posting, name='postingform')
]
index.html
<a href='{% url 'postingform' %}'>Upload your beer now!</a>

Since you defined an app_name in your urls.py, yo need to specify the name of the view with the app_name:
<a href='{% url 'posting:postingform' %}'>Upload your beer now!</a>

Related

Django - Reverse for view function not found

I am using Django 1.11.21 and I am trying to load my application in a Django project. I keep getting this error:
Reverse for 'wfpdocs_browse' not found. 'wfpdocs_browse' is not a valid view function or pattern name.
This is how my template looks like:
<li id="nav_staticmaps">{% trans "Static Maps" %}</li>
In my urls.py file I have:
url(r'^$', TemplateView.as_view(template_name='wfpdocs/document_list.html'), name='wfpdocs_browse'),
This application used to work but after an update it stopped.
My urls.py file looks like this:
urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='wfpdocs/document_list.html'), name='wfpdocs_browse'),
url(r'^rss/$', WFPDocumentsFeed(), name='wfpdocs_rss'),
url(r'^api/', include(api.urls)),
url(r'^upload/$', login_required(DocumentUploadView.as_view()), name='wfpdocs_upload'),
url(r'^(?P<slug>[\w-]+)/$', wfpdocs.document_detail, name='wfpdocs_detail'),
url(r'^(?P<slug>[\w-]+)/update$', login_required(DocumentUpdateView.as_view()),
name="wfpdocs_update"),
url(r'^(?P<slug>[\w-]+)/remove$', wfpdocs.document_remove, name='wfpdocs_remove'),
url(r'^(?P<slug>[\w-]+)/download/?$', wfpdocs.document_download, name='wfpdocs_download'),
]

Django - redirect from one app to another app's page Django

I have two apps called shop and subapp_gallery . Basically, subapp_gallery contains photo albums.. In my shop app I have my homepage for the website. so how can I redirect from link in a homepage[links to each albums] to subapp_gallery's albums path.both apps are working without errors. Thanks in advance.
--image attached down--
>shop_project
>>settings.py
>>urls.py
>shop
>>apps.py
>>models.py
>>urls.py
>>views.py
>subapp_gallery
>>apps.py
>>models.py
>>urls.py
>>views.py
This is urls.py file in shop app >>
from django.urls import path
from . import views
urlpatterns = [
path('', views.shop, name='shop-home'),
path('about', views.about, name='shop-about'),
path('pricing', views.pricing, name='shop-pricing'),
]
This is urls.py file in subapp_gallery app >>
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^(?P<topic_name>\w+)/$', views.topic, name='topic'),
url(r'^(?P<topic_name>\w+)/(?P<photo_id>[0-9]+)/$', views.detail, name='detail')
]
shop app
subapp_gallery app
It's silly question. just used "{% url 'topic' %}"and It worked. django is smart enough to know which name from which application.
You're looking for naming url patterns
You can use reverse('<namespace>:<urlname>') to get the url you want to redirect to.

Django - is not a registered namespace

I am trying to process a form in django/python using the following code.
home.html:
<form action="{% url 'home:submit' %}" method='post'>
views.py:
def submit(request):
a = request.POST(['initial'])
return render(request, 'home/home.html', {
'error_message': "returned"
})
urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^submit/$', views.submit, name='submit')
]
when I try to run it in a browser I get the error:
NoReverseMatch at /home/ u'home' is not a registered namespace
and another error message indicating a problem with the form.
You should just change you action url in your template:
<form action="{% url 'submit' %} "method='post'>
On the note of url namespaces...
In order to be able to call urls using home namespace you should have in your main urls.py file line something like:
for django 1.x:
url(r'^', include('home.urls', namespace='home')),
for django 2.x and 3.x
path('', include(('home.urls', 'home'), namespace='home'))
In your main project, open url.py first. Then check, there should be app_name declared at first. If it is not, declare it.
For example, my app name is user info which is declared in url.py
app_name = "userinfo"
urlpatterns = [
url(r'home/', views.home, name='home'),
url(r'register/', views.registration, name='register')
]
I also faced the same issue.
it is fixed now by adding
app_name = "<name of your app>"
in app/urls.py
For Django 3.0, if you're handling your urls within the app and using include with path, in your project/urls.py:
urlpatterns = [
path(os.getenv('ADMIN_PATH'), admin.site.urls),
path('', include('my_simple_blog.urls', namespace='my_simple_blog')),
path('account/', include('account.urls', namespace='account')),
]
You need to specify namespace in include.
And then in your app/urls.py:
app_name = 'account'
urlpatterns = [
path('register/', registration_view, name='register'),
path('logout/', logout_view, name='logout'),
path('login/', login_view, name='login'),
]
The app_name must match the namespace you've specified in project/urls.py.
Whenever you're referring to these urls, you need to do it like this:
{% url 'namespace:name' %}
If you're using it with redirect:
return redirect('namespace:name')
For the namespace error,
Make sure you have linked the app's url in the main urls.py file
path('app_name/',include('app_name.urls'))
also in the urls.py of your app,make sure you mention the app's name as
app_name='app_name'
Also make sure you have registered the app's name on your installed apps in settings.py
As azmirfakkri has said if you're using redirect, dont use this {% url 'namespace:name' %} syntax, use return redirect('namespace:name').
Probably 2 things could be a root cause,
in app/urls.py do include as below
app_name = 'required_name'
and in project urls.py also include the app_name
url(r'^required_name/$',views.home,name='required_name'),
Check: register app in settings.py INSTALLED_APPS
tag name must be unique in the urls.py file inside your application package inside the project! it is important for the template tagging to route whats what and where.
now [1] inside the urls.py file you need to declare the variable appName and give it the unique value. for example appName = "myApp"; in your case myHomeApp and [2] also define the urlpatterns list...
urlpatterns = [..., url(r'^submit/$', views.submit, name='submit'), ...];
in the html file just change the url tag to:
<form action="{% url 'myHomeApp:submit' %}" method='post'>
this should sifuce... else just write here and we'll see how to continue on
A common mistake that I always find is when you have some name space in your template,
and in YourApp.url you don't have any name space so if you should use name space add
in YourApp.url something like this
app_name = "blog"
then on your temples make sure you add your name space,
so you will have some thing like this "assumption errors are coming from edit.html"
then on that particular template you will do this
"{% url 'blog:vote' pk=post.pk %}" "{% url 'blog:post_category' category.name %}"
if you happen to be nesting include(s, the namespace compounds, eg. topappname:appname:viewname
Maybe someone will find this suggestion helpful.
Go to your applications urls.py and type this before the urlpatterns:
app_name = 'Your app name'
I got the same error below:
NoReverseMatch at /account/register/ 'account' is not a registered
namespace
So, I set "app_name" with the application name "account" to "account/urls.py" as shown below then the error above is solved:
# "account/urls.py"
from django.urls import path
from . import views
app_name = "account" # Here
urlpatterns = [
path("register/", views.register_request, name="register")
]
Check your urls.py
urlpatterns = [
re_path(r'^submit/expense/$', views.submit_expense, name='submit_expense'),
re_path(r'^submit/income/$', views.submit_income, name='submit_income'),
re_path(r'^register/$', views.register, name='register'),
]
then open template.html
put for example register register in your HTML tag like this:
<a class="navbar-brand" href="{% url 'register' %}">
For anyone who struggled on this error like me: After reading the solutions to this question, I was setting namespace in include function in a wrong urls file. Make sure you are modifying the right urls file. For me it was putting it in the main url.py besides settings.py. I hope this answer helps anyone who was confused as I was.
This worked for me:
In urls.py
urlpatterns = [
path("admin/", admin.site.urls),
path("", views.index),
path("test/", views.test, name = 'test')]
In views.py:
def test(request):
return render(request, "base/test.html")
In the template:
href="{% url 'test' %}"

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
...

Adding username in url after base url in django

I am working on django project(which is at verge of completion) and I have structure like something below:
project name: Mysite
App name: myapp
project urls : 127.0.0.1/myapp/blog etc
my requirement is to exclude my app from website (through out) and adding usernames in profile page like:
127.0.0.1/blog
127.0.0.1/products
127.0.0.1/search
and for profile page:
127.0.0.1/simer123/myprofile
I have took from various SO questions and able to exclude the "myapp" part from my urls.
and Also able to include "username" in url for specific page.
SO question1 SO question2 these questions really helped and I found a way out to include user name in my url.
But now again I am stuck because throughout the project I have used things like:
return HttpResponseRedirect(reverse_lazy('myapp:myprofile'))
And similarly in template part like:
<a href="{% url 'myapp:myprofile' %}">
How can I manage to convert them?
Can Anyone explain this with some example.
Thanks
Update:
urls.py file in mysite folder looks like below:
urlpatterns = [
url(r'^autocomplete/', include('autocomplete_light.urls')),
url(r'^$', 'myapp.views.index'),
url(r'^', include('myapp.urls', namespace="myapp")),
url(r'^myapp/', include('myapp.urls', namespace="myapp")),
url(r'^admin/login', adminLogin),
#url(r'^static/(?P<path>.*)$', views.serve),
url(r'^media/(?P<path>.*)$', 'django.views.static.serve', {
'document_root': settings.MEDIA_ROOT,
}),
url(r'^(?P<username>\w+)/', include('myapp.urls', namespace="myapp")),
url(r'^(?P<username>\w+)/myapp/', include('myapp.urls', namespace="myapp")),
]
urls.py in myapp folder includes urls like below:
urlpatterns = [
# ex: /myapp/
url(r'^autocomplete/', include('autocomplete_light.urls')),
url(r'^$', views.index, name='index'),
url(r'^about/$', views.about, name='user_about'),
url(r'^login/$', views.login, name='login'),
url(r'^newaccount/(?P<uid>.*)/$', views.newaccount, name='newaccount'),
url(r'^logout/$', views.logout, name='logout'),
url(r'^myprofile/$', views.profile, name='profile'),
]
Your base url doesn't need to mention myapp at all, just set your url that includes myapp to r'^'. You can still namespace the urls and everything the same as before.
You can pass a kwargs dict to your reverse and reverse_lazy function in order to mapping it with your url pattern.
reverse_lazy('myapp:profile', kwargs={'username': username})
And in your template, just pass it as positional argument
<a href="{% url 'myapp:profile' username %}">

Categories