Django TemplateDoesNotExist, but traceback reaches views.py - python

I have a begin.html file that I'm trying to access at localhost:8000/begin, but I get the DjangoTemplateDoesNotExist error when trying to access it.
The only thing in that template is
<h1>welcome to my app !</h1>
and it's in the app/template directory.
In the same app directory is my views.py file, which contains
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render
# Create your views here.
def begin(request):
print("DEBUG STATEMENT")
return render(request, "template/begin.html", {})
The return statement in begin is reached, as both the print statement and the traceback tell me, but Django can't find the template after.
If it's relevant, my urls.py file is
from django.conf.urls import url
from django.contrib import admin
from app.views import begin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^begin/$', begin, name = 'begin')
]
in the project directory.

Since you have not provided the information, i take it as you mean urls.py inside your app. If you have two urls.py you need to redirect from the first urls where django looks to the other one.
from django.conf.urls import include
urlpatterns = [
url(r'^', include('YOURAPPNAME.urls'))
]
In your appdirectory in urls.py write
from . import views //importing views from current directory
urlpatterns = [
url(r'^begin/$' views.begin, name=begin)
]
Another tip, consider using render_to_response when you are using a http response, i know render is newer but since you're using a response i would go with render_to_response in your case, and skip the context.
return render_to_response('YOURAPPNAME'/begin.html)

Check if your template structure like this,
your_app_name
--> **templates**
--> **your_app_name**
--> **'begin.html'**
--> static
--> models.py
--> ........
Then, change your views, like this,
return render(request, "your_app_name/begin.html", {})
Django as default check for the directory under the name "templates", in your app_directory.
When accommodating multiple apps, for easiness ​templates are kept under the directory with app_name.
From the docs,
It’s possible – and preferable – to organize templates in subdirectories inside each directory containing templates. The convention is to make a subdirectory for each Django app, with subdirectories within those subdirectories as needed.
Do this for your own sanity. Storing all templates in the root level of a single directory gets messy.
When APP_DIRS is True, DjangoTemplates engines look for templates in the templates subdirectory of installed applications. This generic name was kept for backwards-compatibility.

Related

How can i test this url in django

Hi friends i'm trying to test this urls but i don't how do that, i have the following code but it doesn't work
# Method of the test
def testViewDeleteUserIsResolved(self):
url = reverse('inventory:viewDeleteUser', args={'idUser': tbUser.objects.first().id})
self.assertEquals(resolve(url).func,viewDeleteUser)
# Url to try
path('viewDeleteUser/?P<idUser>[0-9a-f-]+', views.viewDeleteUser, name='viewDeleteUser'),
I don't know what reverse('inventory:viewDeleteUser') stands for. I am also a newbie to Django, but I think it will work if you change it to reverse('viewDeleteUser').
tests.py
from django.urls import reverse
from .views import viewDeleteUser
def testViewDeleteUserIsResolved(self):
url = reverse('viewDeleteUser', args={'idUser': tbUser.objects.first().id})
self.assertEquals(resolve(url).func,viewDeleteUser)
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('viewDeleteUser/?P<idUser>[0-9a-f-]+', views.viewDeleteUser, name='viewDeleteUser'),
]
In a Django app you have to create a url.py file where all your urls live, you have to put that path() instruction you have in that file.
Then your function needs to be in the views.py file, also take in count the name of the function has to be the same you're declaring in the path() as far I see you you're using views.viewDeleteUser so in the views.py file you need a function like this:
def viewDeleteUser:

How do I map urls to views in Django, getting AttributeError: module 'myproject.views' has no attribute

I just started learning django and running the tutorial part 3, decided to see if I understood the mapping from urls.py to views.py.
I got views and urls to work in the polls app, but then I wanted to make views in the project folder, so I made a views.py file in the project folder (see code below), with a view/function , which I named 'home'.
I then edited the urls.py in the project-folder(see below). run the server, It worked! visiting the url: http://localhost:8000/
it responded:
Hello, world. You're at the HOME PAGE.
BUT.. when I tried to make another view in same views.py called: morn, and adding the url for it, then error (see below),
http://localhost:8000/morn
returning:
localhost refused to connect.
I DID IT EXACTLY THE SAME WAY, so just when I thought I understood it, I didnt get it at all?!?!
The difference between the two views are just their name and path, why doesnt it work then?
on a linux manjaro
Python 3.8.1
Django 3.0.3
#
#this is my urls.py (which I made myself), in the project folder
from django.urls import include, path
from django.contrib import admin
from . import views
#from views import morn
admin.autodiscover()
urlpatterns = [
#lager en index-side
path('', views.home, name='home'),
path('morn/', views.morn, name='morn'),
path('admin/', admin.site.urls, name='admin'),
path('polls/', include('polls.urls')),
]
#
#this is the views.py in myproject folder, same folder as
from django.http import HttpResponse
def home(request):
output = 'Hello, world. You\'re at the HOME PAGE.'
return HttpResponse(output)
def morn(request):
output = 'Hello, world. Youre at the morn-path.'
return HttpResponse(output)
ERROR from konsole running the morn-view:
File "/home/nr1/dev/django/myproject/myproject/urls.py", line 29, in <module>
path('morn/', views.morn, name='morn'),
AttributeError: module 'myproject.views' has no attribute 'morn'
Oh no... I just got it! :)
I have put the views.py file in both of the myproject-folders and the urls.py is just in the inner myproject-folder. I was then updating just the outer views.py-file, when I thought I was in the inner views.py, so, ofcourse, the urls.py couldnt find the new function, it was searching the wrong views.py (outer one).
a lot of frustration for nothing.. but I learnt, I learnt!

Where to implement python classes in Django?

I'm learning Django on my own and I can't seem to get a clue of where I implement a regular Python class. What I mean is, I don't know where do the Python classes I write go. Like they go in a separate file and then are imported to the views.py or are the classes implemented inside the views.py file?
Example I want to implement a Class Alphabet, should I do this in a separate file inside the module or just implement the functions inside the views.py file?
I don't know where do the Python classes I write go. Like they go in
a separate file and then are imported to the views.py.
Example I want to implement a Class Alphabet.
It's just a matter of getting your import statement correct:
django_proj1/
django_proj1/
myapp/
myclasses.py
views.py
Then in your view:
#myapp/views.py:
from myapp.myclasses import Alphabet
Or, you could do it like this:
django_proj1/
django_proj1/
myclasses.py
myapp/
views.py
And in your view:
#myapp/views.py:
from django_proj1.myclasses import Alphabet
Response to comment:
And after I successfully imported my class, how do I pass the
attributes to an HTML template?
The following is straight from the official django tutorial.
myapp/views.py:
from django.shortcuts import render
from django.http import HttpResponse
from myapp.myclasses import Alphabet #<*** Import your class.
from django.template import RequestContext, loader #<*** Import stuff for the template.
# Create your views here.
def index(request):
alph = Alphabet()
result = alph.change('hello') #Your class produces some result here.
template = loader.get_template("myapp/index.html")
context = RequestContext(request, {
'x' : result #<*** Make a variable named x available in your template.
})
return HttpResponse(template.render(context))
The directory structure looks like this:
django_proj1/
django_proj1/
myapp/
myclasses.py
views.py
templates/ <***Create this directory
myapp/ <***Create this directory
index.html <***Create this file
myapp/templates/myapp/index.html:
{% if x %}
<div>The result you requested was: {{x}}</div>
{% else %}
<div>Sorry, couldn't get the result.</div>
{% endif %}
myapp/myclasses.py:
class Alphabet:
def change(self, word):
return word + 'Z'
Start the server:
.../my_django_projects/django_proj1$ python manage.py runserver
url in your browser:
http://localhost:8000/myapp/
You should see:
The result you requested was: helloZ
If you comment out the following line in myapp/views.py:
context = RequestContext(request, {
#'x' : result #<*** Make a variable named x available in your template.
})
Then the template will send the else portion of index.html to the browser:
Sorry, couldn't get the result.
django_proj1/django_proj1/urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
from . import views
urlpatterns = patterns('',
# Examples:
# url(r'^$', 'dj1.views.home', name='home'),
# url(r'^blog/', include('blog.urls')),
url(r'^admin/', include(admin.site.urls)),
url(r'^myapp/', include('myapp.urls')),
)
django_proj1/myapp/urls.py:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
]
Django is just Python at the end of the day.
You can create new modules anywhere in your project, and import them into your views, models, urls, etc. This is often how you'd organize general utils (utils.py).
You can deliver data to your views in a few ways, for instance:
from your_module import some_object
class MyView(TemplateView):
template_name = 'some_template.html'
def get_context_data(self, **kwargs):
context = super(MyView, self).get_context_data(**kwargs)
context['my_data'] = some_object.some_method()
return context
And in some_template.html: {{ my_data }}
It depends on the scope of the Alphabet class. If it is a utility class then I would suggest to put in a utils.py file, for example. But it is perfectly fine to have classes in the views.py file, mainly those dealing with UI processing. Up to you.
Distinct to similar frameworks, you can put your Python code anywhere in your project, provided you can reference them later by their import path (model classes are partially an exception, though):
Applications are referenced by their import path (or an AppConfig import path). Although there's some magic involving test.py and models.py, most of the times the import / reference is quite explicit.
Views are referenced by urls.py files, but imported as regular python import path.
Middlewares are referenced by strings which denote an import path ending with their class name.
Other settings you normally don't configure are also full import paths.
The exception to this explicitness is:
models.py, test.py, admin.py : They have special purposes and may not exist, providing:
You will not need any model in your app, and will provide an AppConfig (instead of just the app name) in your INSTALLED_APPS.
You will not rely on autodiscovery for admin classes in your app.
You don't want to make tests on your app, or will specify a non-default path for your app-specific test command run.
templates and static files: your project will rely on per-app loaders for your static files and for your templates files, and ultimately there's a brute-force search in each of your apps: their inner static/ and templates/ directories, if exist, are searched for those files.
Everything else is just normal python code and, if you need to import them from any view, you just do a normal import sentence for them (since view code is imported with the normal Python import mechanism).

Create a view in django

Very new to django. I'm using version 1.5.2 and I just did a fresh install. I'm using the django development server; I'll be moving to Apache down the road, but I want to understand the django's particular flavor of MVC methodology before doing taking that step.
So I start up the django server with `python manage.py runserver 0.0.0.0:8000' through the terminal in my project directory (django_books). I get this error:
ViewDoesNotExist at /
Could not import django_books.views.home. Parent module django_books.views does not exist.
So my view doesn't exist. My view.py file is empty because the tutorial I was following did not include one. I'm not sure if this is the problem. If it is, how do I create this file (what goes in it)?
Directory Structure:
django_books
beer (from the tutorial lol)
migrations
__init__.py
models.py
views.py
random_book
(same as beer above)
django_books (this is my actual django project, beer and random_book are apps)
__init__.py
settings.py
urls.py
wsgi.py
media
.gitignore
manage.py
requirements.txt (output from pip freeze command)
urls.py
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'^$', 'django_books.views.home', name='home'),
# url(r'^django_books/', include('django_books.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)),
)
If you keep your urls.py the way it is, that means you need to create views.py within /django_books/django_books/
Within that file, create a new function called home.
Alternately, if you have any functions inside of /django_books/beer/, you could reference them from urls.py.
All urls.py does is expose a python path to a function and route a URL there. So you can see that you don't have a module or file called views within django_books/django_books, which is why you get the failure.
View is basically a python function that receives HTTP Request and returns HTTP Response.
Quote from docs:
A view function, or view for short, is simply a Python function that
takes a Web request and returns a Web response. This response can be
the HTML contents of a Web page, or a redirect, or a 404 error, or an
XML document, or an image . . . or anything, really. The view itself
contains whatever arbitrary logic is necessary to return that
response. This code can live anywhere you want, as long as it’s on
your Python path. There’s no other requirement–no “magic,” so to
speak. For the sake of putting the code somewhere, the convention is
to put views in a file called views.py, placed in your project or
application directory.
This line url(r'^$', 'django_books.views.home', name='home'), in urls.py points the index / of your site to the home view - you should create it.
Create a python function called home in views.py:
from django.http import HttpResponse
import datetime
def home(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
Restart your development server and visit http://127.0.0.1:8000.
FYI, read the tutorial more carefully, part 3 is about dealing with urls and views.

Django - Import views from separate apps

I'm new to Django and working my way through "The Django Book" by Holovaty and Kaplan-Moss. I have a project called "mysite" that contains two applications called "books" and "contact." Each has its own view.py file. In my urls.py file I have the following:
from books import views
from contact import views
...
urlpatterns = patterns('',
...
(r'^search/$', views.search),
(r'^contact/$', views.contact),
...
When I run my code I get this error:
NameError at /search/
...
Exception value: 'module' object has no attribute 'search'
What I believe is happening is that since views from contact was imported last, Django is looking at contact's view which does not contain search (search is in books' view).
What is the proper way to import the views.py file from two distinct applications within a Django urls file?
Thanks for your help!
Disclaimer: Not a Django answer
The problem is with these two lines:
from books import views
from contact import views
The second import is shadowing the first one, so when you use views later you're only using the views from contact.
One solution might be to just:
import books
import contact
urlpatterns = patterns('',
...
(r'^search/$', books.views.search),
(r'^contact/$', contact.views.contact),
...
I'm not sure, but I also think that you don't actually need to import anything and can just use strings in your pattern, something like: 'books.views.search'.
Another possiblity is to follow Simon Visser suggestion:
from books.views import search
from contact.views import contact
from books import views
from contact import views
You are overwriting the name views. You need to import them as different names or as absolute names.
import books.views
import contact.views
... or ...
from books import views as books_views
from contact import views as contact_views
Then use the correct name when defining your URLs. (books.views.search or books_views.search depending on the method you choose)
The reason I’m answering this question is because it was answered years ago and those answers are not correct or useful anymore for newer Django versions, or there is a better practice you should know about.
So, if you have more than one app in your Django project then you should use a new urls.py file for every one of your apps. It means that if you start a new app then you have to manually create a new file called urls.py in the subfolder of your new app. Many beginners first do not understand why this is good, but this is a good practice if you plan creating more apps in one Django project.
When you start a project, the urls.py file automatically created in your project folder, but if you create/start a new app in Django, then it is a good practice if you create a separate urls.py for that app in its own folder. (And that way you will never have the "importing different app's views into urls.py" problem in the first place).
After you created the urls.py file for your app, then you have to include that app’s urls.py file in your project’s urls.py file in the following way:
Let’s see an example when you create a new app called ‘my_new_app’.
This is how your project’s main urls.py file should look like:
from django.conf.urls import url, include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^my_new_app/', include('my_new_app.urls')),
]
In your project’s urls.py file you have to import the ‘include’ method, then you can include your my_new_app urls.py file in your project’s main urls.py file. In your my_new_app folder you have to manually create a urls.py file as I stated above. Then you have to use that file for all of your urlpatterns of your my_new_app. Then of course this way it’s going to be automatically included in your project’s main urls.py file.
So this is then how your my_new_app own urls.py file should look like:
from django.conf.urls import url
from my_new_app import views
urlpatterns = [
url(r'^$', views.index, name = "index"),
]
Assuming that you also created a first view called ‘index’ in your ‘my_new_app/views.py file.
my_new_app/views.py file look like this:
from django.shortcuts import render
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello World!")
And you can check your my_new_app in your browser at:
http://localhost:8000/my_new_app
(Of course you can give any url to your my_new_app in your project's urls.py file.)
Now, you can create another app, in your Django project, called my_second_app and you should repeat the above steps for that app too. This way you will not have any problem importing views from different apps into urls.py files. This would be a very basic “good practice solution” for this problem in 2017 in Django 1.11.
The URLconfs documentation gives an example of the same situation
You can skip the imports and separate the urls by app as such:
urlpatterns = patterns('books.views',
(r'^/book/search/$', 'search'), #calls books.views.search
)
urlpatterns += patterns('contact.views', #make note of the '+='
(r'^/contact/search/$', 'search'), #calls contact.views.search
)
Heres the approach i took for different view/API versions:
from django.urls import path
from my_app import views as api_v1
from my_app import views_v2 as api_v2
urlpatterns = [
path('view_one', api_v1.ViewOne.as_view()),
path('view_two', api_v2.ViewTwo.as_view()),
]

Categories

Resources