"admin" Subdirectory Triggering (unintentially) Django Admin Pages - python

I am having trouble with some custom admin pages triggering the Django admin site instead of displaying my custom pages.
My urls.py follows:
urlpatterns = patterns('',
# ... trimmed ...
# Admin pages
url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
url(r'^admin/', include(admin.site.urls)),
# Lobby Visitor Log
url(r'^visitorLog', include('lobbyVisitorLog.urls')),
)
In my lobbyVisitorLog app I have the following directory structure, leading to "admin" pages
lobbyVisitorLog
- templates
- admin
And my lobbyVisitorLog/urls.py follows:
urlpatterns = patterns('visitorLog.views',
url(r'^/$', views.home, name='homeView'),
url(r'^/search', views.search, name='searchView'),
url(r'^/submit', views.submit, name='submitView'),
url(r'^/admin/$', views.adminView, name='adminView'),
url(r'^/admin/import/$', views.adminImportView, name='adminImportView'),
url(r'^/(?P<guest_type>\w+)$', views.logEntry, name='logEntryView'),
)
The views.py for the admin index page looks like this:
def adminView(request):
return render(request, 'admin/index.html', {}, context_instance=RequestContext(request))
When I go to "mysite/visitorLog/admin/" I get the Django admin site with the following message: “You don't have permission to edit anything.”
However, if I change my "admin" directory to "utils" (or whatever else, other then "admin") and update my views.py accordingly, everything appears as expected! This is okay, I can deal with my directory being called "utils" but it will annoy me... just enough.
What is happening that is causing the Django admin page to load instead of my custom pages?

By default django first checks each of the paths you have in TEMPLATE_DIRS for 'admin/index.html'. If it doesn't find it there, it starts searching in the templates directory for each app in the INSTALLED_APPS setting.
If 'django.contrib.admin' is listed first in INSTALLED_APPS, it will use the identically named 'admin/index.html' template from the django.contrib.admin app.
Moving 'django.contrib.admin' to the last position in INSTALLED_APPS should allow it to find 'admin/index.html' in your lobbyVisitorLog app first, but this will break the admin site by cause it to use 'admin/index.html' from your app, lobbyVisitorLog.
A good way to solve this is to always have a sub-directory named after your app within your app's templates directory. For example:
lobbyVisitorLog
- templates
- lobbyVisitorLog
- admin
- index.html
and then update your view's template path:
def adminView(request):
return render(request, 'lobbyVisitorLog/admin/index.html', {}, context_instance=RequestContext(request))
You can find more on how Django loads templates here

Related

How to include urls with app_name without having to use reverse with app name in Django?

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.

What is the url.py file that opens home using wagtail?

I'm starting using Wagtail + Django.
Generally, in Django you set the urls path in a urls.py file.
However, I cannot find the url.py that says to my app, when users visits main domain (local http://127.0.0.1:8000/) show home_page.html view.
I'm following the get_started tutorial.
And used this command to generate the basic apps:
wagtail start elim
This generated: a) elim, b) home, c) search apps.
Only elim app contains a urls.py, but it doesn't set a path for home:
from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from wagtail.admin import urls as wagtailadmin_urls
from wagtail.core import urls as wagtail_urls
from wagtail.documents import urls as wagtaildocs_urls
from search import views as search_views
urlpatterns = [
url(r'^django-admin/', admin.site.urls),
url(r'^admin/', include(wagtailadmin_urls)),
url(r'^documents/', include(wagtaildocs_urls)),
url(r'^search/$', search_views.search, name='search'),
]
This is my project structure:
So how does going to "/" open the home page???
The home dir is served by wagtail internal mechanism. Scroll to the end of the file elim/urls.py to find this :
urlpatterns = urlpatterns + [
# For anything not caught by a more specific rule above, hand over to
# Wagtail's page serving mechanism. This should be the last pattern in
# the list:
url(r"", include(wagtail_urls)),
# Alternatively, if you want Wagtail pages to be served from a subpath
# of your site, rather than the site root:
# url(r"^pages/", include(wagtail_urls)),
]
So, continue to read the tutorial, I'm sure you will soon or later discover the Page models and everything provided by wagtail.
Try adding a view function in your app's views.py file that renders home_page.html when the user goes to "/".
in views.py write this:
def home_page(response):
return render(response, "home/home_page.html")
then map this to ur urs.py file
url_patterns = [
path("", views.home_page)
]
then add this url to your url conf

Refer to my (reusable) app's url namespace in Django

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.

django reset-password views, NoReverseMatch error and also problems with templates

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'

How to set the project root url when Wagtail is integrated as an app in a Django-project

I'm integrating Wagtail in a pre-existing Django project.
My project tree is as follows:
/adjangoproject/
/anapp
/blog/
urls.py
/anotherapp
urls.py
My adjangoproject/urls.py
urlpatterns = patterns('',
url(r'^blog/', include('geonode.blog.urls')),
[...]
My adjangoproject/blog/urls.py
urlpatterns = patterns('',
url(r'^cms/', include(wagtailadmin_urls)),
url(r'', include(wagtail_urls)),
)
While [adjangoproject_rooturl]/blog/cms correctly shows the wagtail admin, the path [adjangoproject_rooturl]/blog/
(the base location where the pages of my wagtail blog shall be served) gives:
Request Method: GET
Request URL: http://127.0.0.1:8000/blog/
Raised by: wagtail.wagtailcore.views.serve
Could you help me?
You need to make sure you have a Site record set up in the admin, under Settings -> Sites. There should be one created by default, but if you deleted the initial homepage and created a new one to replace it, this will have been lost, and you'll need to set up a new one.

Categories