Still learning Django and for some reason I have difficulty grasping some concepts especially the url / template / view mappings. Attempting to reirect a FormView to a "Complete" page I have the following:
urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('', IndexView.as_view(), name='index'),
path('forgotid/', ForgotId.as_view(),name="forgotid"),
path('forgotid/complete/',ForgotIdComplete.as_view(),name="forgotid_complete"),
path('forgotpwd/', ForgotPwd.as_view(),name="forgotpwd")
]
views.py
from django.shortcuts import render
from django.views.generic import FormView, TemplateView
from .forms import LoginForm, ForgotIDForm
class IndexView(FormView):
template_name = "login/index.html"
form_class = LoginForm
class ForgotId(FormView):
template_name = "login/forgotid.html"
form_class = ForgotIDForm
success_url = 'complete/'
class ForgotIdComplete(TemplateView):
template_name = "login/forgotid/complete/forgotid_complete.html"
def get(self, request):
return render(request, self.template_name, None)
class ForgotPwd(TemplateView):
template_name = "login/forgotpwd.html"
submitting the ForgotID form should redirect me to the success_url but I get an error stating that the template could not be found. Can someone please explain what and why I am doing this incorrectly.
The error I am receiving is:
TemplateDoesNotExist at /login/forgotid/complete/
My folder structure:
EDIT
I found the issue. The template name in the ForgotIdComplete class should read: login/forgotid_complete and notlogin/forgotid/complete/forgotid_complete.html
change your success_url to this.
from django.core.urlresolvers import reverse_lazy
class ForgotId(FormView):
template_name = "login/forgotid.html"
form_class = ForgotIDForm
success_url = reverse_lazy('forgotid_complete')
This error means that, django wanted to render the template from the path you provided but couldn't find it on the disk.
Go to settings.py and make sure that templates is configured to your actual templates directory.
PROJECT_DIR = os.path.realpath('.')
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [(os.path.join(PROJECT_DIR, 'templates'))],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
I found the issue. The template name in the ForgotIdComplete class should read:
login/forgotid_complete
and not
login/forgotid/complete/forgotid_complete.html
Related
Currently I have in settings set my main directory to the templates folder so that I have a project level templates. Within that folder I have a home.html file.
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / "templates"],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
This is my views.py file:
from django.views.generic import TemplateView
class HomePageView(TemplateView):
template_name: "home.html"
Whenever I runserver I receive this error: ImproperlyConfigured at /
TemplateResponseMixin requires either a definition of 'template_name' or an implementation of 'get_template_names()'
I'm following a book to the T (Django for Beginners) and I'm unsure why this error could be happening. Has the syntax for template_name changed? I've checked all the documentations and my name seems to be okay. I've also tried to input the pathname to the file instead.
You are making an annotation: you should use an equals sign = instead of a colon ::
from django.views.generic import TemplateView
class HomePageView(TemplateView):
template_name = 'home.html'
Normally templates are also "namespaced" by putting these into a directory with the name of the app, so:
from django.views.generic import TemplateView
class HomePageView(TemplateView):
template_name = 'app_name/home.html'
and thus put the template in the directory of the app_name/templates/app_name/home.html. This prevents that you later would collide with a template with the same name in a different app.
You have used the view incorrectly. Replace the : with = and it should be fine.
I am using python 3.7.2 and Django 2.1 and every time I try to load the home url I get the following error.
TemplateDoesNotExist at /
ghostwriters/post_list.html
Request Method: GET Request URL: http://localhost:8080/ Django
Version: 2.1 Exception Type: TemplateDoesNotExist Exception Value:
ghostwriters/post_list.html
Exception Location:
C:\Users\User.virtualenvs\ghostwriter-HT06mH6q\lib\site-packages\django\template\loader.py
in select_template, line 47 Python Executable:
C:\Users\User.virtualenvs\ghostwriter-HT06mH6q\Scripts\python.exe
Doesn't make any sense because there really is no post_list.html and its not in my app level urls.py or my views.py so why is this happening?
urls.py:
from django.urls import path from .views import PostListView
urlpatterns = [
path('', PostListView.as_view(), name='home'), ]
views.py:
from django.shortcuts import render from django.views.generic import
ListView
from .models import Post
class PostListView(ListView):
model = Post
template = 'home.html'
settings.py:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
If you are using any CBV(Class Based Views), by default django will look for template with some specific pattern. In your case, since you are using List View, it will look for YOURMODELNAME_list.html (YOURMODELNAME in lowercase), If you are extending Detail View, it will look for YOURMODELNAME_detail.html .if you want to override this behavior, within your CBV try this,
class YourCBV(ListView):
template_name = 'your_new_template.html'
For your reference,
Django official documentation
I am using iFrame with Django 2.0.13. I keep getting TemplateDoesNotExist error, and I don't see what I'm missing.
I've looked at other answers here on StackOverFlow and I seem to be doing everything.
settings.py
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATE_DIR = os.path.join(BASE_DIR,'templates')
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATE_DIR],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
urls.py
from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView
from NatureApp import views
urlpatterns = [
path('', views.index, name="index"),
path('NatureApp/', include('NatureApp.urls')),
path('admin/', admin.site.urls),
path(r'Map2.html', TemplateView.as_view(template_name="Map2.html"), name='Map2'),
]
views.py
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
# def index(request):
# return HttpResponse("Hello World!")
def index(request):
my_dict = {'insert_me':"Hello I am from views.py!"}
return render(request,'NatureApp/index.html',context=my_dict)
Map2.html should being showing. I see index.html fine, but inside the IFrame I see the TemplateDoesNotExist message.
I'm new to Django, I'm trying to include all code needed for troubleshooting.
Try creating Map2 view in views.py. There could be problem with TemplateView.as_view()
I have not figured out how I can present a website with pure HTML code and/or HTML + JavaScript + CSS.
I tried to load an HTML file that just says: Hello World.
I know I can do that with Django too, but later on, I want to display my website with CSS+JavaScript+HTML.
In the views file I run this code:
# Create your views here.
from django.http import HttpResponse
from django.template import Context, loader
def index(request):
template = loader.get_template("app/index.html")
return HttpResponse(template.render)
But the only thing the website displays is:
If your file isn't a django template but a plain html file, this is the easiest way:
from django.shortcuts import render_to_response
def index (request):
return render_to_response('app/index.html')
UPDATE 10/13/2020:
render_to_response was deprecated in Django 2.0 and removed in 3.0, so the current way of doing this is:
from django.shortcuts import render
def index (request):
return render(request, 'app/index.html')
You are not calling the render method there, are you?
Compare:
template.render
template.render()
If your CSS and JS files are static don't use Django to serve them, or serve them as static files
For your html you could do the same if it is just some fixed file that won't have any dynamic content. You could also use generic views with the TemplateView, just add a line like this to your urls.py:
url(r'^path/to/url', TemplateView.as_view(template_name='index.html')),
By using HttpResponse you can send data only, if you want to html file then you have to use render or render_to_response by following ways...
from django.shortcuts import render
def index(request):
return render(request, 'app/index.html')
or
from django.shortcuts import render_to_response
def index (request):
return render_to_response('app/index.html')
First, you need to do some settings for templating:
Create "templates" folder in the root directory, where manage.py is located after you created your project.
Then go to settings.py , in the TEMPLATES section enter the directory of templates folder. Hard coding is not recommended because if you send your project to your friend, your friend won't be able to run it. Should be like this:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,"templates")],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
Assuming that you have home.html and about.html have in templates folder:
urls.py
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('admin/', admin.site.urls),
path('about/',views.aboutview),
path('',views.homeview),
]
views.py
from django.http import HttpResponse
from django.shortcuts import render
def aboutview(request):
return render(request,"home.html")
def homeview(request):
return render(request,"about.html")
from django.http import HttpResponse
from django.template import loader
def index(request):
template=loader.get_template('app/index.html')
return HttpResponse(template)
I got this error during the python django project
I do not understand why the template does not connect.
Please let me know which part of the error it is and let me know how to fix it.
How can I to do?
Attach an error picture.
enter image description here
settings.py
INSTALLED_APPS = [
--- skip ---
board.apps.BoardConfig',
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
These are my project sub-lists
/mysite
/board
/migrations
/templates
/board
board_list.html
board_detail.html
search.html
__init__.py
admin.py
apps.py
forms.py
models.py
tests.py
urls.py
views.py
/mysite
__init__.py
settings.py
urls.py
views.py
wsgi.py
/static
css
js
image
/templates
base.html
main.html
db.sqlite3
manage.py
/mysite/mysite/urls.py
from django.contrib import admin
from django.conf.urls import url, include
from .views import MainHome
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', MainHome.as_view(), name='main'),
url(r'^board/', include('board.urls', namespace='board'),
]
/mysite/board/urls.py
from django.conf.urls import url
from .views import *
from mysite.views import MainHome
app_name = 'board_app'
urlpatterns = [
url(r'^$', MainHome.as_view(), name='main'),
url(r'^search/$', SearchFormView.as_view(), name='search'),
url(r'^boards/$', BoardList.as_view(), name='board_list'),
url(r'^boards/(?P<slug>[-\w]+)/$', BoardDetail.as_view(), name='board_detail'),
]
/mysite/borad/views
from .models import Board
from django.views.generic import ListView
--- skip ---
class BoardList(ListView):
model = Board
template_name = 'board_list.html'
content_object_name = 'boards'
paginate_by = 10
--- skip ---
In /mysite/borad/views, you have:
template_name = 'board_list.html'
Replace it with:
template_name = 'board/board_list.html'
Because board_list.html is inside templates/board.
Edit
In settings.py, you have:
'DIRS': [os.path.join(BASE_DIR, 'templates')],
which means that Django will look for templates in your mysite/templates folder. Remove it like this:
'DIRS': []
so Django will look by default inside templates/ directory for every installed app.
Your template is inside board directory. And your model template name is not referencing to that path.
In your class BoardList add template_name = 'board/board_list.html'
I'd try a systematic approach:
in settings.py, define TEMPLATE_DIR = os.path.join(BASE_DIR,'templates')
Given your directory structure, your app name is board not board_app. So, set INSTALLED_APPS = [..., 'board']. Also, I don't understand in your code why you refered to board.apps.BoardConfig instead of board, maybe am I missing something
TEMPLATES = [{ .... 'DIRS': [TEMPLATE_DIR], ... }] will make things more visible
in urls.py of board app, set app_name=board
in views.py, if you use Django naming conventions for file / directories, you don't need to specify the template name for class based views. Remove template_name = 'board_list.html provided your template is in board/templates/board/board_list.html
Also, reboot the server after performing those changes.
Does this help?