vanity urls clashing with admin urls django - python

I want to have vanity urls in my django application i.e. user's profile at url like example.com/username . I tried to do it like shown:
urlpatterns = patterns('',
#sitemap generation
url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps},name='django.contrib.sitemaps.views.sitemap'),
url(r'^grappelli/', include('grappelli.urls')), # grappelli URLS
url(r'^admin/', include(admin.site.urls)),
..other urls
#User Profile URLs
url(r'^(?i)(?P<username>[a-zA-Z0-9.-_]+)$','myapp.views.user_profile',name='user-profile'),
)
As url pattern for vanity urls is at last in urlpatterns so django should match it at the last. But even though its conflicting with the admin urls and user_profile view renders 'example.com/admin' url instead of default.What's the best way of ensuring that vanity-urls do not clash with any of the django-urls ? Is there anyway to write regex such that it excludes the set of existing urls of the django application.

Your middleware redirects /admin/ to /admin. This does not match the regex for the admin, only for your user profile. With this middleware you cannot reach the admin index page.
One solution is to only redirect if the old path, with slashes, is invalid and the new one is valid.

Related

Django URL namespace 'admin' isn't unique. for endpoints with and without slash

I am getting this warning and I would like to get rid of it...
My urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('admin', admin.site.urls),
re_path(r'^(?P<Model>[A-Za-z]+)',
GenericViewSet.as_view({'get': 'list', 'post': 'create'}),
) # aka model endpoint
]
What I want to achieve is a request to /admin and /admin/ to fall to the admin site and any other request will be passed to my generic model handling API.
The problem is that when I set only path('admin/', admin.site.urls), a request to /admin falls to the model endpoint and when I set only path('admin', admin.site.urls), a request to /admin/ falls to the model endpoint. I get why this happens, Django goes through all endpoints before adding the slash to the end and going through them again with appended slash.
So I have to specify both admin and admin/ path, to make both requests to /admin and /admin/ fall to the admin site and that is causing the warning to appear... Which probably should not be happening...
Can I go somehow around this? (Without changing my desired url paths...)
p.s. I have APPEND_SLASH set to True
EDIT:
When I use only
urlpatterns = [
path('admin/', admin.site.urls),
]
both requests to /admin and /admin/ fall correctly to admin page.
I see the problem now. If you only set admin/ and don't set admin, this gets matched with your regular expression.
From APPEND_SLASH documentation (emphasis mine):
...if the request URL does not match any of the patterns in the URLconf and it doesn't end in a slash, an HTTP redirect is issued to the same URL with a slash appended.
So, django is not redirecting admin to admin/ because your regex pattern is matching with admin as your expression doesn't contain a slash in the end.
You should specify a slash and dollar sign in your regex pattern so that django matches the complete url with the slash.
This should work:
path('admin/', admin.site.urls),
re_path(r'^(?P<Model>[A-Za-z]+)/$', ...),

Django media page not found 404

I'm trying to learn to work with Django and i'm making a image app.
Now I managed to upload images to my database, but now I want to retrieve them.
The images are stored in media/images/.
Now I made an admin page that looks like this:
AS you can see the thumbnails don't load.
When You click on one of those thumbnails, I get the following error:
Page not found (404)
Request Method: GET
Request URL: http://127.0.0.1:8000/media/images/june.png
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^admin/
The current URL, media/images/june.png, didn't match any of these.
Here is my urls.py of my main thinghy (not the app, wich is called photo):
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'mysite.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
)
Now I'm not sure what I exactly need to do to fix this.
I hope you can help me.
Please be clear ( small steps ) cause I'm not that experienced with django.
Thanks in advance
Oh BTW i'm on Win7
EDIT:
this is what I added to my settings/py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/http://127.0.0.1:8000/media/'
So right now, your urls.py doesn't have a pattern for /media/images. That pattern probably exists somewhere in your photo app. You need to link the urls for your photo app into your primary urls.py, something like:
url(r'^media/', include('photo.urls')),
This would tell the app that if it sees a url with media/ it should look for the next thing ('images/') in the photo app.

Django "homepage" app urls.py issue

I am pretty new to Django and when I laid my site out I did it in the following way:
The project is a "portal" of sorts,
App 1 "home" is the app that houses the homepage, login, registration
and other "site-wide" functionality
App 2 "inventory" is a basic asset inventory
App 3 "dashboard" is a set of status dashboards based on assets in the inventory
Right now I am trying to add the login functionality and I have a main project urls.py that looks like this:
File: /portal/urls.py
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^$', include('home.urls'), name='home'),
url(r'^admin/', include(admin.site.urls), name='admin'),
url(r'^inventory/', include('inventory.urls'), name='inventory'),
url(r'^dashboard/', include('dashboard.urls'), name='dashboard'),
url(r'^capacity/', include('capacity.urls'), name='capacity'),
)
My plan is to use the inclusion of .../home/urls.py to manage any site-wide functionality such as logging in, registering, etc.
Right now the home index view shows just fine, but anything else in .../home/urls.py gives me a 404
File: /home/urls.py
from django.conf.urls import patterns, url
from home import views
urlpatterns = patterns('',
url(r'^test/$', views.index, name='home_test'),
url(r'^ajax_login/$', views.ajax_login, name='ajax_login'),
url(r'^$', views.index, name='home_index'),
)
At this point I suppose my question is two-fold: Am I approaching this correctly? If so, how can I get the desired functionality? If not, how should I change the way things are set up/laid out to do it the correct "best practices" way?
Thanks in advance!
EDIT
Got it working thanks to dt0xff and holdenweb, accepted holdenweb's answer since it was more accurate including the need to put the home url inclusion below the rest.
Here is my new portal/urls.py file for reference
File: /portal/urls.py
from django.conf import settings
from django.conf.urls import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls), name='admin'),
url(r'^inventory/', include('inventory.urls'), name='inventory'),
url(r'^dashboard/', include('dashboard.urls'), name='dashboard'),
url(r'^capacity/', include('capacity.urls'), name='capacity'),
url(r'^', include('home.urls'), name='home'),
)
The issue is with your first pattern, which will only match the empty URL. So any empty URL will cause the home/urls.py URLs to be analyzed, but only the empty one will match even in that.
Unfortunately if there is no common prefix then that pattern "^" will match every URL (since they all start at the beginning ...).
So you should either use a common prefix for all the pages, or put the home URL specification at the end to give the other URLs a chance to match before it is tested.
Django looks in urls like this:
Get list of root urls - portal/urls
Find first, which matches to current url
If it is include, go to included urls, cutting off matched part
Your problem is here
url(r'^$', include('home.urls'), name='home'),
I mean, here
'^$'
You want url to match "start and then end of url". It works good with root(dunno.com/), but not with others, because url will contain something more...
So, just remove $ and you are fine
url(r'^', include('home.urls'), name='home'),
you never need to add regex($) at project/urls.py

Can't find page in django

I'm currently learning Django and I'm trying to add form to register a User.
Now my problem starts really early because I get a 404 whenever I try to access my registration page.
My 3 files are as follows:
views.py : just a hello world to display basically
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello World")
def registration(request):
return HttpResponse("Registration page")
urls.py (in my project) :
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
(r'^$', include('myapp.urls')), # index with login/registration
(r'^grappelli/', include('grappelli.urls')), # grappelli URLS
(r'^admin/', include(admin.site.urls)), # admin site
)
and finally urls.py (in my app) :
from django.conf.urls import patterns, url
from myapp import views
urlpatterns = patterns('',
url(r'^$',views.index, name='index'),
url(r'^registration/$',views.registration, name='registration'),
)
When I go to my normal index (localhost:8000) It displays the hello world I wrote in the views.py file. However when I try to go the registration page it just returns me a 404 (localhost:8000/registration).
Now as I said I'm still learning this whole thing, but I don't get why It doesn't work properly. As far as i understand the r'^$' in the project file is pointing towards the localhost:8000 and the same regex in the app file tells it to load the index page in this location. Now as the program is still in localhost:8000, a r'^registration/' should be loading the other page in localhost:8000/registration right?
It would be really nice if you could explain to me why this doesn't work and where I did a mistake in my thoughts.
This is the error I get:
When i take
(r'^randomstringhere/', include('myapp.urls')), # index with login/registration
instead of
(r'^$', include('myapp.urls')), # index with login/registration
I can get to the registration page via localhost:8000/randomstringhere/registration. But Site is meant to have a selection where you can either Log in or register on localhost:8000 (or future domain www.randomdomainhere.com) and a registration/login form on localhost:8000/login, localhost:8000/registration (www.randomdomainhere.com/registration etc.)
At the end of each url you should add a $ symbol,
url(r'^registration/$',views.registration, name='registration'),
reffer this https://docs.djangoproject.com/en/1.4/topics/http/urls/
you are missing $ sign in the end of url.
It should be:
url(r'^registration/$',views.registration, name='registration'),
The $ symbol in django urls means end-of-string match character which is borrowed from regular expression. So, $ should be added at the end of your url on app's urls.
url(r'^registration/$',views.registration, name='registration'),
However we can write urls with the regular expressions that don’t have a $ (end-of-string match character) but we do have to include a trailing slash(/). For urls without $, you must enter the trailing slash while opening the url in your browser to match the regular expression.
Your app urls in project's urls.py is
url(r'^grappelli/', include('grappelli.urls')), # grappelli URLS
So, to access the registration page, you need to browse by
localhost:8000/grappelli/registration/
i.e. append the path in your app's url to the path in project's url for the app.
Learn more about urls here.
You need to remove $ from the first url as given below
urls.py (in my project) :
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
(r'^', include('myapp.urls')), # index with login/registration
(r'^grappelli/', include('grappelli.urls')), # grappelli URLS
(r'^admin/', include(admin.site.urls)), # admin site
)
A url starts with ^ and ends with $. so if $ is encountered django understands that the url has ended and there's nothing more infront of that. so in your case it will no more look for "registration". or if your url with "registration" doesnt matches to any urls specified at all.

Page not found (404) in django tututorial

I'm working through https://docs.djangoproject.com/en/1.4/intro/tutorial02/ .
after changing the urls.py to
from django.conf.urls import patterns, include, url
# Uncomment the next two lines to enable the admin:
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'mysite.views.home', name='home'),
# url(r'^mysite/', include('mysite.foo.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
url(r'^admin/', include(admin.site.urls)),
)
I get the following when I start the runserver:
404 error
Using the URLconf defined in mysite.urls, Django tried these URL patterns, in this order:
^admin/
The current URL, , didn't match any of these.
Is there anything obvious that I'm doing wrong?
Thanks in advance,
Bill
You don't have a base url defined. You need something like -
urlpatterns = patterns('',
# ...
url(r'^$', HomeView.as_view())
)
You should be able to see your site at - localhost:8000/admin/ (assuming you're running your dev server with python manage.py runserver).
Django checks all the URL's you've defined in your url conf file and looks for one that matches the url you've entered in the browser. If it finds a URL that matches then it serves up the http response returned by the url's corresponding view (HomeView in the code above). The urls.py file is matching url's to views. Views return the http response.
Looking at the error message you've got (and the code you've included from the url.py file), you can see that there's only one url defined in your app - admin/. Trying to get a page at any other url will fail.
For more information have a look at the docs for django's URL Dispatcher.

Categories

Resources