Django - Loading Robots.txt through generic views - django

I have uploaded robots.txt into my templates directory on my production server. I am using generic views;
from django.views.generic import TemplateView
(r'^robots\.txt$', TemplateView.as_view(template_name='robots.txt', content_type='text/plain')),
However, when I load robots.txt on the browser I get a 404 - Page not found.
Can someone suggest what needs to be done to fix this. Thanks.
I should point out that on the local environment this seems to be working.

Finally got it. I had to add a '/' in ^robots.txt$
(r'^robots\.txt/$', TemplateView.as_view(template_name='robots.txt', content_type='text/plain')),
That's elementary! I presumed that by default APPEND_SLASH it True however, on the production server it didn't work.
Let me know if anyone can provide some insights on it.

Related

Django URL to Template View Preventing Media Folder from Displaying

I have been working on a Django DRF/Vue project and ran into issues with being able to download or view files from the media folder. I have this set up as a media root and directory in the settings and included the following in my url.py file:
if settings.DEBUG:
urlpatterns += static(
settings.STATIC_URL,
document_root = settings.STATIC_ROOT
)
urlpatterns += static(
settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT
)
The issue is happening from my path to the template views.
re_path(r"^.*$", IndexTemplateView.as_view(), name="entry-point")
If I comment this line out, the media directory works as I want but this causes my application to no longer direct users to my frontend and Django template files. I am fairly new to Django and am not sure exactly how to resolve this, or if it is possible to create a condition within the path to exclude /media from being triggered?
Edit: I was able to make this somewhat work by changing re_path(r"^.*$", IndexTemplateView.as_view(), name="entry-point") to path('', IndexTemplateView.as_view(), name="entry-point"). My app currently runs Django on port 8000 and Vue app on port 8080. I access the app front end from 8080, which allows it to re-direct to the login page if necessary. If I try to refresh any page with this updated config, I am faced with the error, "Using the URLconf defined in app.urls, Django tried these URL patterns, in this order:"... and it shows a list of my api URLs. I find URL patterns with Django one of the most confusing things about trying to learn this framework. Can someone please explain to me what is causing this?
I was stuck on this for a long time and finally figured it out. Of course it was a really simple fix. All I had to do, after changing the 're_path' to 'path' was change the Vue route type to hash instead of history.

Django Custom Error Handlers in Apache and mod_wsgi

I have custom 404 and 500 error handlers setup in django and they work in development, but with Apache they just show the default apache Internal Server Error page, even for 404 errors.
Here is my urls.py:
handler400 = 'views.error400'
handler403 = 'views.error403'
handler404 = 'views.error404'
handler500 = 'views.error500'
I've read of many ways to set up custom error pages in apache, but all of the approaches I tried with django did not work. What is the correct way to set this up for Apache/mod_wsgi and Django?
Do I remove those lines from my urls.py and add some lines to my apache.conf?
What lines should be added to apache.conf as I'm not sure how to access views from the apache configuration file and the normal urls.py routing for Django is not working for the custom error pages since as I suspect Apache is intercepting the requests and providing it's own pages.
I just want to use my templates for my custom error pages (which include inheriting from a base template).
How can I achieve this, I can't find a decent answer anywhere?
Thanks
EDIT:
I tried editting the Apache config to add ErrorDocument 500 /templates/500.html and such but it did not work.
I currently have the error page in my templates directory, they each inherit from a base template. Also, they each have their own view to handle the responses.
But no matter what I do, removing those lines from urls.py, adding stuff to apache config, etc. I can't get anything but the typical Internal Server Error apache page to display on any error, even one's that aren't 500 errors.
What can I do to get this working? Worked fine on the django development server, but as soon as apache was thrown into the mix I can't get it to work using either apache or django, I must be missing something but what?
You can remove those lines from urls.py. Django will look up to your templates to get those.
Just put 404.html and 500.html files into your_app/templates/ directory.

Integrating Sphinx and Django in order to require users to log in to see the documentation

I am curious if it is possible to hide sphinx documentation inside a django app so that only people who log in can see it. It seems to me that since sphinx creates its own structure and that Django uses the urlconf to define which pages a user can see, that it wouldn't be possible to combine the two. Although there must be some combining since the Django website likely uses django and sphinx. I am wondering if anyone has any insight or if they can point me in the right direction.
Thank You in Advance!
Sphinx builds your docs into HTML files, so in most cases this docs should be served by your web server rather then Django. However Django is able to serve static files as well.
You can use the django.views.static.serve function to do this and wrap this function with login_required. E.g:
from django.views.static import serve
from django.contrib.auth.decorators import login_required
urlpatterns += patterns('',
url(r'^docs/(?P<path>.*)', login_required(serve), {'document_root': '/path/to/sphinx/build/html'}, 'docs'),
)
However this configuration will be considered a bad practice in production environment as in this case Django will serve both html and css/js files from your sphinx theme.
The first improvement you can do here is to serve /path/to/sphinx/build/html/_static/ with apache/nginx or whatever you use.
The more proper way is to serve docs with apache/nginx and make it handle the auth itself. Unfortunately I made a quick Google search but did not find a way to use Django's User model to handle http_auth in apache or other. Alternatively you can use something like mod_sendfile or X-Accel modules - http://www.wellfireinteractive.com/blog/nginx-django-x-accel-redirects/ In a nutshell - Django app checks permission if user can view the file and add special header to response containing file path. Webserver will serve this file instead of original message from django

Django 1.5 robots.txt

Here is what we have in our url conf:
from django.views.generic import TemplateView
.....
url(r'^robots\.txt$', TemplateView.as_view(template_name='robots.html')),
For some reason, we're getting redirected to ?next=robots.txt when attempting to hit *.com/robots.txt
Is there something obvious we're missing ? This seems to work locally in vagrant environments but it's not working in production (redirecting through ?next=)
update 1
There is no obvious reason that this would be behind a #login_required decorator or any required login function...
update 2
Sure enough, you can see robots.txt when you are authenticated....
update 3 direct_to_template has been deprecated, I'm sure that used to work but apparently has been deprecated in django 1.5
update 4 seems like this post has a way to force login_required for a TemplateView.as_view: How to require login for Django Generic Views? but it seems in our case this is being force by default ?

Apache | Django: How to run websites on the back of a base URL?

I've got a base url. http://baseurl.com/
I'm trying to run projects on the back of it. For example
http://baseurl.com/mongoose/
The projects run but the URL don't work properly because they all
reference the base url. So for 'About Me' page it points to
http://baseurl.com/about instead of http://baseurl.com/mongoose/about
Is this something i need to change in django or apache? Is what I'm
trying to do even possible?
Coming from an IIS .net background I know that in IIS you can "Create and application" within a site which essentially does what I'm trying to achieve now with Apache and Django.
Thanks
You shouldn't need to do anything. Apache is supposed to be setting a request header called SCRIPT_NAME, which is your base URL, and all URL reversing takes that into account.
How are you creating these URLs in your templates?
Update
So your problem is with getting the URLs of Flatpages. The issue is that the normal way of calculating URLs dynamically, so that they do take SCRIPT_NAME into account - using the reverse() function or the {% url %} tag - doesn't work with Flatpages, because they are not dispatched via urls.py but via a custom middleware which fires on a 404.
So instead of using that middleware, I would use the urls.py mechanism to dispatch to flatpages. Remove the flatpagemiddleware from your settings.py, and in urls.py at the end of your patterns add this:
url(r'^(?P<url>.*)$', 'django.contrib.flatpages.views.flatpage', name='flatpage'),
Now, in your templates, you can do:
<a href="{% url flatpage page.url %}">
and it should work correctly.
Check any urls.py in the project(s) to see if they expect to be top-level. But if the application outputs links like /something then it's going to mean the root directory. The application should be reversing a view/parameter into a URL, which would allow you to move it around. If you wrote the apps, check out reverse in django.core.urlresolvers