I am writing a GUI application using Django 1.1.1.
This is the views.py:
from django.http import HttpResponse
def mainpage(request):
f=open('pages/index.html','r').readlines()
out=''''''
for line in file:
out+=line
print out
return HttpResponse(out)
I am trying to load the contents of index.html which is inside a folder pages inside the GUI application folder.
My project's urls.py is
from django.conf.urls.defaults import *
from gui.views import *
urlpatterns = patterns('',
(r'^/$', mainpage)
)
When I run the server I get a 404 error for the root site.
How can I load the index.html file through views?
If you require just simple output of html page, this can be achieved by simply putting following into urls.py:
(r'^$', 'direct_to_template', {'template': 'index.html'})
For the root page don't use r'^/$', just r'^$', because this ^ means "start of the string after domain AND SLASH" (after 127.0.0.1/ if you run app on localhost). That's why localhost:8080// works for you.
Edit: check yours paths too. Do you have 'pages' directory in the same directory that views.py is?
Anyway: it seems that you are trying to do something bad and against Django architecture. Look here for tutorial on writing your first application in Django.
Your actual code in the view is incorrect. Here is my fixed up version:
from django.http import HttpResponse
def mainpage(request):
lines=open('loader/pages/index.html','r').readlines()
out=''''''
for line in lines:
out+=line
print out
return HttpResponse(out)
Note that in your code the line that reads from the file is:
f=open('pages/index.html','r').readlines()
You open the file and read the lines into f and then try to iterate over lines. The other change is just to get my path to the actual index file right.
You might want to read this http://docs.djangoproject.com/en/dev/howto/static-files/ if you want to serve static pages.
Got it! ;)
It seems that the mainpage function actually runs on the urls.py (as it is imported from the views.py) file so the path I must provide is gui/pages/index.html. I still had a problem, 'type object not iterable', but the following worked:
def mainpage(request):
f=open('gui/pages/index.html','r').readlines()
return HttpResponse(f)
And url pattern was r'^$' so it worked on http://localhost:8080/ itself.
Related
I have a django app and a view for the home page where I want to use a static html file for the homepage. My file structure is like this:
project/
stats (this is my app)/
urls.py
views.py
stats.html
(other files here)
In my views.py I have the following code:
from django.shortcuts import render_to_response
def index(request):
return render_to_response('stats.html')
When I run the urls, I just have the index page. I go to the stats page and I receive a TemplateDoesNotExist Error. Looking for an answer I tried to put stats/stats.html instead for the path, but I still get the same error. What is the correct way of doing this?
In your project directory, add a directory called 'templates' and inside the templates directory, create 'stats' directory. Put your HTML file in the stats directory.
Then change your settings file at the bottom from
TEMPLATE_DIRS = (
os.path.join(SETTINGS_PATH, 'templates'),
)
To
TEMPLATE_DIRS = (
os.path.join(BASE_PATH, 'templates'),
)
You can arrange your project like this
project/
stats (this is my app)/
urls.py
views.py
stats.html
templates/
stats/
stats.html
In your views.py, write this:
def index(request):
return render_to_response('stats/stats.html')
make sure there is 'stats' in the INSTALLED_APPS list in the settings.py.
I am trying to create an index page for my home app using Django. I would like for the urls.py file to point directly to an index.html file in my templates folder within the home app. Therefore, I have the following:
urlpatterns = patterns('',url(r'^$',template_name='index.html'),)
This gives me an error when I load the page, however.
url() got an unexpected keyword argument 'template_name'.
All the resources I have looked at have a view instead of directly linking to an html, but I simply want to go to an index page. How can I achieve this? Thank you!
As per Django documentation:
This would be a proper way of doing it:
from django.conf.urls import patterns
from django.views.generic import TemplateView
urlpatterns = patterns('',
(r'^about/', TemplateView.as_view(template_name="about.html")),
)
I am new to django..
When I was working before 2 days..it was working properly..
Now django index page shows ..
ViewDoesNotExist at /
Could not import mysite.views.home. Parent module mysite.views does not exist.
my url.py contain
url(r'^$', 'mysite.views.home', name='home'),
please help me.
Where I did mistake??
Is the views.py that you are referring to in the project root? Error message says it can't find that file so check the path. If you moved the home view into an app folder, make sure you configured your settings file to include the app and point to the app folder as app_folder.views.home
Seems like a mistake in your views.py. Could you add the home view code?
I want to open a html file i.e map.html which is saved in same directories where i saved this views.py and urls.py. (django based platform)
I wrote this sample code for views.py (to load map.html) but it is not working:
from django.template import Template, Context,RequestContext
from django.http import HttpResponse
import datetime
def router_map(request):
fp = open('./map.html')
t = Template(fp.read())
fp.close()
html = t.render(Context({'router_map'}))
return HttpResponse(html)
and my urls.py is:
from django.conf.urls.defaults import *
from umit.views import router_map
urlpatterns = patterns('',
(r'^index/$', router_map),
)
The problem is, I think, that you are using the path './map.html'. This is means that Python will try and find the current directory of the program, not the same directory as the view file is in.
Lets say the Django project is in the directory /home/foo/myproject. If you cd to that directory and run python manager.py runserver, the current directory inside the application (i.e. the directory .) will be /home/foo/myproject, which is not what you want.
The easiest way to fix this is to use the full path to the file in your call to open:
fp = open('/home/foo/myproject/myapp/views/map.html')
I'm running the 1.4.2 appengine SDK locally on a windows machine. I have an application running Django 0.96. The template rendering is using the django wrapper from
google.appengine.ext.webapp.template.render
to render templates. I often use a relative path to link my templates e.g
{% extends "../templates/base.html" %}
After upgrading to Django 1.2 the find_template method from
django.template.loader in the appengine's Django 1.2 lib folder is now raising a TemplateDoesNotExist when the relative paths are used
for loader in template_source_loaders:
try:
#raises TemplateDoesNotExist name='../templates/home.html' dirs=None
source, display_name = loader(name, dirs)
return (source, make_origin(display_name, loader, name, dirs))
except TemplateDoesNotExist:
pass
raise TemplateDoesNotExist(name)
I've been stepping through the Django and AppEngine code for a while now but can't see any reason for this. Can anyone provide any more insight?
Thanks,
Richard
This problem bit me too when I converted from 0.96 to 1.2 Django templates. I was initially pushed to do so when SDK 1.4.2 started issuing the warning that I needed to pick a version, but when I looked into the much-needed improvements in the template language, I was eager to make the change.
And then everything broke. Like you, I used a lot of relative paths in my extends and include commands. It took a lot of debugging and digging, but I did figure out the cause of the problem and a pretty good solution.
The cause: in Django 1.2, the code that loads template files started using a command called safe_join to join path parts (you can see the code in google_appengine\lib\django_1_2\django\template\loaders\filesystem.py) . It won't allow relative paths to go above what it thinks of as the top-level directory. This is the same thing as a web server being configured to prevent you gaining access to the server's whole filesystem just by sticking some ..'s into your URL. The end result is that the
{% extends "../templates/base.html" %}
that used to be just fine breaks the rules and it isn't going to work.
The way that I fixed this in my application without completely restructuring how my templates are laid out is by implementing a custom TemplateLoader. Django's template rendering engine allows an application to have many different classes that know how to find templates in different ways. If you look in the directory that I gave above, you'll see that there are several provided, and they are all classes that inherit from BaseLoader. I provided my own that is custom-tailored to how my templates are laid out.
My project has a Rails-like lay-out:
app/
controllers/
home_controller.py
posts_controller.py
models/
...
views/
home/
index.html
about.html
posts/
show.html
new.html
shared/
base.html
post.html
Every template extends base.html and a couple include post.html, and they previously used relative paths to get to their location in base/. Ideally, I didn't even want to use the .. up-dir to get there, but it was required with 0.96. I created the following template loader to work with my scheme:
from django.conf import settings
from django.template import TemplateDoesNotExist
from django.template.loader import BaseLoader
from django.utils._os import safe_join
import os
class MvcTemplateLoader(BaseLoader):
"A custom template loader for the MVCEngine framework."
is_usable = True
__view_paths = None
def __init__(self, views_path):
self.views_path = views_path
# We only need to instantiate the view_paths class variable once.
if MvcTemplateLoader.__view_paths is None:
temp_paths = []
for each_path in os.listdir(views_path):
# We want to skip hidden directories, so avoid anything that starts with .
# This works on both Windows and *NIX, but could it fail for other OS's?
if not each_path.startswith('.'):
full_path = os.path.join(views_path, each_path)
if each_path == "shared":
# The shared directory is special. Since templates in many other directories will be
# inheriting from or including templates there, it should come second, right after the
# root views directory. For now, it will be first.
temp_paths.insert(0, full_path)
else:
temp_paths.append(full_path)
# The root views_path itself will always be first in order to give resolution precendence to templates
# that are specified with a parent directory. In other words, home/index.html will be immediately
# resolved with no ambiguity; whereas, index.html could resolve as bar/index.html rather than
# foo/index.html.
temp_paths.insert(0, views_path)
MvcTemplateLoader.__view_paths = temp_paths
def get_template_sources(self, template_name):
for template_dir in MvcTemplateLoader.__view_paths:
try:
yield safe_join(template_dir, template_name)
except UnicodeDecodeError:
# The template dir name was a bytestring that wasn't valid UTF-8.
raise
except ValueError:
# The joined path was located outside of this particular
# template_dir (it might be inside another one, so this isn't
# fatal).
pass
def load_template_source(self, template_name, template_dirs=None):
tried = []
for filepath in self.get_template_sources(template_name):
try:
file = open(filepath)
try:
return (file.read().decode(settings.FILE_CHARSET), filepath)
finally:
file.close()
except IOError:
tried.append(filepath)
error_msg = "Could not find %s in any of the views subdirectories." % template_name
raise TemplateDoesNotExist(error_msg)
load_template_source.is_usable = True
_loader = MvcTemplateLoader
And I caused my custom template loader to be included in the collection that Django tries by changing my application's main function to look like this:
def main():
from google.appengine.dist import use_library
use_library('django', '1.2')
os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
from django.conf import settings
views_path = os.path.join(os.path.dirname(__file__), 'app','views')
settings.TEMPLATE_LOADERS = (('gaemvclib.mvctemplateloader.MvcTemplateLoader', views_path), 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader')
(and then all the rest of the stuff that normally goes into your main function).
So, I think that you should be able to modify the TemplateLoader code above to match how you have your template directories laid out, and it will give you a greater control over not only how you layout you templates hierarcy but also how you write your extends and include statement. You no longer use .. but rather just give the path of the template relative to whatever in your project is the equivalent of my views directory.
One reason you get the error message TemplateDoesNotExist: templates\AdminListstr.html
Doublecheck the slash you use between "templates" and your template name. I wasted a few hours, then checked the value being returned by os.path.join.
In summary you need to insure you are using "/" not the Windows "\". If you use the wrong slash, your code will work on (Windows) development but fail when deployed.
My diagnostic code printed this: look at the last slash
And the value returned by os.path.join is:/base/data/home/apps/s~myapp/1.356037954289984934/templates\LabListstr.html
Aye yi yi!