How to limit catch all urls in django - django

I have a django project with specific urls, setup by a 'catchall' URL.
This is so I can go to mysite/living, and have it pass living as a parameter and pull up the appropriate details from my db.
My urls.py:
url(r'^$', views.index, name='index'),
url('about/', views.about_view, name='about_view'),
url('contact/', views.contact_view, name='contact_view'),
url('(?P<colcat>[\w\-]+)/collection/(?P<name>[\w\-]+)$', views.collection_detail, name='collection_detail'),
url('(?P<colcat>[\w\-]+)/$', views.collection_view, name='collection_view'),
I am running into the problem where, anything can be passed as a parameter. This is particularly notable with search engines, where mysite/index.html/index.html returns a valid page.
Is there a way to limit the urls that are 'allowed' to be matched?

It is very unlikely for a user to enter/modify URLs manually while browsing. Everyone just googles and clicks whatever link is shown by the search engine. So, You just need to restrict what the search engine indexes.
This can be done by adding a sitemap.xml file to the root of your website.
sitemap.xml specifies all the urls of your website along with some additional information inorder to make it easier for search engines to crawl. If you don't add a sitemap.xml, search engines try to crawl through every possible url. If added they wont.
There is already a sitemap generating framework provided by django: https://docs.djangoproject.com/en/2.1/ref/contrib/sitemaps/

Related

Redirecting old urls to new urls in Django

After publishing site in Django, I changed my slugs and now old pages show as errors in Google search. Is there a way to automatically redirect them without having to write an individual redirect for each page?
There are a few things you need to do to make sure that your website gets crawled properly.
In regards to the redirection, you can use django.http.HttpResponsePermanentRedirect to perform the redirection. Just keep the view, and when a user navigates to this view, redirect them to the proper URL.
You should also create a sitemap, which lists out all of the URLs for your website. You can then submit this sitemap to google using their webmaster tool if you have not already done so. This will inform their crawler of all the pages that they need to crawl without worrying on them missing some information

Moving the API Root of Default Router in Django

I'm using Django 1.8 and Django REST Framework. I want the API Root functionality of using a Default Router, but I want to move it to another url, like /apiroot/ or something like that.
I found this post, but it doesn't really answer my question. I don't want to rewrite the API, I basically just want the functionality of the ^$ route to be a standard template page (home page) for the site, and have site.com/apiroot to be the new API root url.
In the process of writing up this question, I looked at the DRF source code, and found my answer. Instead of deleting the question, I figured I'd go ahead and post it, since someone else may be wondering the same thing, and a search hasn't turned up any answers to this already.
The solution to this was to add the following lines to my urls.py:
url(r'^$', media_views.index, name='index'),
url(r'^apiroot/', router.get_api_root_view()),
The first line will replace the ^$ url entry with a pointer to my index method in media_views. The second will mimic the DefaultRouter functionality from / to /apiroot/ and show the API root page there instead.

How are Django page templates assigned to each page?

I couldn't find this info in the Django docs, but I'm sure it is there, I'm just very new and don't know what terms/etc to search on.
How are Django page templates assigned to each page?
I have a login to a Django site, and also SFTP access to the site. I don't think my Django login is a superuser/full-admin though because the interface seems pretty limited compared to other CMS systems. I can edit pages, posts and the media library, but I don't see anything that says how each page is assigned a template.
For example, I have this file /mysite/templates/pages/index.html
I know that template is being used for the home page because it has all of the content that is specific to the home page on it, and changes I make show up on the home page.
I tried copying that file to test.html, but when I browse to test.html in my browser, I get a 404 error (I also get that error if I go to index.html). So there must be something else that maps a template to a page, but I'll be dambed if I can find it. Will I need more access to the admin area, or can I do something with SFTP? I also have SSH access but wasn't able to follow any of the steps online to create a new superuser account for me, for Django.
Edit: Thanks for both answers, after I work through this I'll accept whichever helped the most. I do not have a views.py file, but I think it might be using an extra module for this routing, I have this in my urls.py file:
urlpatterns = patterns("",
("^admin/", include(admin.site.urls)),
url("^$", "mezzanine.pages.views.page", {"slug": "/"}, name="home"),
("^", include("mezzanine.urls")),
)
Is this "mezzanine" something different which changes the answer (location of views.py or list of views)?
url.py is the file that maps the urls to methods that return rendered templates. In essence you define the url and a method and when someone goes to that url, that method gets called which returns a HTTP response with the rendered template. This map is called urlpatterns. In the following example when someone goes to yourwebsite/blog then in the blog apps, view.py, page method is called, which will use a template and render that with specific information.
urlpatterns = patterns('',
url(r'^blog/$', 'blog.views.page'),
url(r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
)
Have a look at this link.
https://docs.djangoproject.com/en/dev/topics/http/urls/
Django uses urls.py files to map paths to views. This match is resolved using regular expressions. When a match is found, Django executes the associated view (usually inside views.py). The view is in charge to render the template required for the path (by finding it on the server's hard disk and loading it).
All aforementioned means that there's no direct association between a url path (i.e www.example.com/path/to/page) and a file on the server's hard disk (i.e /server/path/to/page). It's all performed dynamically by Django's engine when a request comes in.
If you want to know which view is gonna be generated for a specific path, follow the regexs at urls.py until you find the path you're looking for. Then open the view for that url and see inside which template it is rendering.
Reading doc's URL Dispatcher is a good point to start learning about this.
Hope this helps!

Best practices for path-agnostic links in Django?

What is the best way to code html links in a Django application
which is intended to be distributed to other users and
where it cannot be known in advance what the final
URL path to the application will be?
Here are some links I am currently using:
<li>By Date</li>
<li>Trends</li>
This works fine when the app is configured like this in mysite/urls.py to
be in the root path.
url(r'^', include('myapp.urls')),
But if you change mysite/urls.py to run the app in a different path:
url(r'^myapp/', include('myapp.urls')),
then the links break. This seems like it ought to be a common scenario but I have been unable to discover how to solve it cleanly.
You want url tag:
Returns an absolute path reference (a URL without the domain name) matching a given view function and optional parameters. This is a way to output links without violating the DRY principle by having to hard-code URLs in your templates

What is the admin url in a Django template (and where is a list of all system urls)?

I was looking at some Django examples and I've noticed that you can call certain urls with a variable like this Log in</li>. How would I call the admin page with the same idea?
A more general question: is there a list of pre-defined url variables that Django uses? And how are they defined (how can they be overridden)? Some other ones I know that exist are auth_logout and auth_password_change.
It generally depends on urls you write in your urls.py.
Relevant Django documentation: https://docs.djangoproject.com/en/dev/topics/http/urls/
When you add django.contrib.admin, you add its urls by using (r'^admin/', include(admin.site.urls)),, which you can view here: https://code.djangoproject.com/browser/django/trunk/django/contrib/admin/sites.py#L217