Template Does not Exist on IIS+Django - django

After the deployment process of my Django website on IIS i am getting an error like below,
TemplateDoesNotExist at /test/new_site/list/
Template-loader postmortem
Django tried loading these templates, in this order:
Using engine django:
django.template.loaders.app_directories.Loader: D:\workspace\One_Site_Project\env_one_site_37\lib\site-packages\django\contrib\admin\templates\test\new_site_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: D:\workspace\One_Site_Project\env_one_site_37\lib\site-packages\django\contrib\auth\templates\test\new_site_list.html (Source does not exist)
django.template.loaders.app_directories.Loader: D:\workspace\One_Site_Project\env_one_site_37\lib\site-packages\rest_framework\templates\test\new_site_list.html (Source does not exist)
I don't know why IIS is searching my templates files in virtualenv directory.
My view rendering code is,
#method_decorator(csrf_exempt, name='dispatch')
class NewSiteListUpdate(View):
"""
This class is used to list all the new site activity, also update an activity
"""
def get(self, request, *args, **kwargs):
"""
List all the activity info or a particular activity info
:param request:
:param args:
:param kwargs:
:return:
"""
if request.user.is_staff:
self.data = ActivityInformation.objects.all()
self.radius = 11111
return render(request, 'test/new_site_list.html', {'data': self.data})
Below is my template settings in settings.py file,
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR + '/template/'],
'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',
],
# 'builtins': [
# 'src.huawei.templatetags.custom_tags'
# ],
'libraries':{
'custom_tags': 'templatetags.custom_tags',
},
},
},
]
Below is my project structure,
This is working fine in my local system. I tried to add the template folder in to the virtual directory also, but no use, still the same error is showing. I followed this tutorial in order to set up my application on IIS.
I am using python 3.7 and IIS 8.5
I spend my two days for solving this issue but i did not find any solution related to this.
Any help would be greatly appreciated. Thanks in Advance.

I think that you have to modify some part in your code
settings.py
try to change 'DIRS': [BASE_DIR + '/template/'], to 'DIRS'=[os.path.join(BASE_DIR, 'template'), ]
views.py
The path made by the render function will be : ../template/huawei/new_site_list.html but in your project structure your don't have a folder huawei. You must write : return render(request, 'test/new_site_list.html', {'data': self.data})

Related

Whats the correct structure for Django templates?

I have a project in Django called: "my_site", and an app called "blog", I'm trying to render the "index.html" inside the path: my_site/blog/templates/blog/index.html. But keep getting this error:
Template-loader postmortem
Django tried loadi
ng these templates, in this order:
Using engine django:
django.template.loaders.filesystem.Loader: C:\Users\Ricardo Neto\Dev\Django_Projects\my_site\templates\index.html (Source does not exist)
django.template.loaders.app_directories.Loader: C:\Python310\lib\site-packages\django\contrib\admin\templates\index.html (Source does not exist)
django.template.loaders.app_directories.Loader: C:\Python310\lib\site-packages\django\contrib\auth\templates\index.html (Source does not exist)
django.template.loaders.app_directories.Loader: C:\Users\Ricardo Neto\Dev\Django_Projects\my_site\blog\templates\index.html (Source does not exist)
The view:
def index(request):
return render(request, 'index.html')
the urls.py:
urlpatterns = [
path('', views.index),
path('posts', views.show_all_posts),
path('posts/<slug:slug>', views.show_post)
]
If i move the index.html outside the blog folder, like in this example: my_site/blog/templates/index.html
the code runs and the index.html renders without problem, but i was taught that the correct structure is to create a folder inside templates with the same name of the app.
So could anyone please explain me the way i should structure my files?
rather than keeping it within the app. I prefer to keep it under the project file. my_site/templates/app_x/index.html
├───accounts
│
├───django_project
│
└───templates
├───accounts
└───registration
In settings.py file update the DIRS to the path of the templates folder. Generally, the templates folder is created and kept in the sample directory where manage.py.
import os
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',
],
},
},
]
If I open separate files under templates, I render them as folder_name/index.html, otherwise directly as index.html.
Django resolves templates relative to the "templates" directory located inside the app directory and chooses the first template across all apps whose name matches. For example, if you have two apps: blog and news both with templates named "index.html" in the "templates" directory, Django would not be able to choose correctly one of them. To make a distinction you can create a subfolder inside the "templates" directory named after the corresponding application: "blog/templates/blog/index.html" and "news/templates/news/index.html". And after that you can use those templates in the view functions like this: render(request, 'news/index.html') and render(request, 'blog/index.html').
You can read about this topic here, check the remark "Template namespacing": https://docs.djangoproject.com/en/4.0/intro/tutorial03/

Cutomize dj_rest_auth Password reset email

I want to send customized emails when a user request a password reset. I am using dj_rest_auth with django. Here is what I have done: 1. Defined a custom serializer that inherits from PasswordResetSerializer of dj_rest_auth
class CustomPasswordResetSerializer(PasswordResetSerializer):
def get_email_options(self):
return {
'html_mail_template_name': 'registration/password_reset_email.html',
}
Then in settings.py pointed to this serializer:
REST_AUTH_SERIALIZERS = {
'LOGIN_SERIALIZER': 'users.serializers.CustomLoginSerializer',
'PASSWORD_RESET_SERIALIZER': 'users.serializers.CustomPasswordResetSerializer',
}
Then configured templates in settings.py
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',
],
},
},
]
Then I created templates folder in project root, created a registration folder inside it and placed password_reset_email.html inside it.
This is what I found as an exact solution formy problem after googling some time,but this is not working for me. What did I miss?
This answer helped me
https://stackoverflow.com/a/70624462/15624533
I just put my files (html or txt) directly to templates folder, and changed 'account/email/password_reset_key' to just 'password_reset_key' in send_mail method.
I faced the same challenge and got the solution from this issue on GitHub. https://github.com/iMerica/dj-rest-auth/issues/9 . It's easier than you think
Create your custom password reset serializer
from dj_rest_auth.serializers import PasswordResetSerializer
class CustomPasswordResetSerializer(PasswordResetSerializer):
def save(self):
request = self.context.get('request')
# Set some values to trigger the send_email method.
opts = {
'use_https': request.is_secure(),
'from_email': 'example#yourdomain.com',
'request': request,
# here I have set my desired template to be used
# don't forget to add your templates directory in settings to be found
'email_template_name': 'password_reset_email.html'
}
opts.update(self.get_email_options())
self.reset_form.save(**opts)
If you only want to customize email parameters nothing more or less, you can ignore overriding save() method and override get_email_options() instead
from dj_rest_auth.serializers import PasswordResetSerializer
class MyPasswordResetSerializer(PasswordResetSerializer):
def get_email_options(self) :
return {
'email_template_name': 'password_reset_email.html'
}
then point to your custom serializer in settings.py
REST_AUTH_SERIALIZERS = {
'PASSWORD_RESET_SERIALIZER': 'path.to.your.CustomPasswordResetSerializer'
}

Template in Django not found

In the code below, my problem is that template file 'UserAccount' is not found. I set the app in the settings and create a directory in the app and an html file in the directory.
from django.shortcuts import render
# Create your views here.
def login(request):
context = {}
return render(request, 'UserAccount/login.html', context)
this should be your settings.py:
INSTALLED_APPS = [
# django essentials
"django.contrib.admin",
...
# my apps
"myapp", #the app name is "myapp"
]
...
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [str(BASE_DIR.joinpath("template"))], # change this line in your settings
"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",
],
},
},
]
now create a directory in the same directory as your apps. sth like this:
myapp
app_two
template
...
now in template directory create another directory with the name of your app. in tha t put your html fiels. like this:
| myapp
| app_two
| template
|----myapp
|----sth.html
|----sth_2.html
|----app_two
now when you want to reference them do it like this:
return render(request, 'myapp/sth.html', context)
General tips on asking question on Stackoverflow:
for title : a summary of your problem with keywords like "django" or "django-views"
for putting your code use three backticks --> code
search a lot before asking question. there is a huge chance that someone had posted the same problem before you and you can find your answer there

Upload custom templates in django

I want users to be able, to upload their custom html templates including css styling and png and jpeg images. These html files shall be retrievable through django. That means that they can see the resulting html content in form of a normal webpage. In order to be able to do that, I (seemingly, don't know a better approach yet) have to upload the html files in the template directory.
This is my current model:
class StylesheetFile(models.Model):
HTML = 'HTML'
CSS = 'CSS'
JPEG = 'JPEG'
PNG = 'PNG'
# Currently supported mimetypes
MIMETYPE_CHOICES = (
(HTML, 'text/html' ),
(CSS , 'text/css' ),
(JPEG, 'image/jpeg'),
(PNG , 'image/png' ),
)
mimetype = models.CharField(max_length=64, choices = MIMETYPE_CHOICES)
company = models.ForeignKey(Company)
file = models.FileField(upload_to=get_upload_path)
And this is the current function to determine the upload_path:
def get_upload_path(instance, filename):
if instance.mimetype == 'HTML':
return os.path.join(
settings.TEMPLATES[0]['DIRS'][1],
instance.company.name,
filename)
if instance.mimetype == 'CSS':
return os.path.join(
"custom_css",
instance.company.name,
filename)
if instance.mimetype == 'JPEG' or instance.mimetype == 'PNG':
return os.path.join(
"custom_img",
instance.company.name,
filename)
Template settings
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
'/home/ubuntu/app/templates/',
'/home/ubuntu/app/custom_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',
],
},
},
]
When I do this the css stylings, png and jpeg files are getting uploaded correctly, but the html files not. I receive following error:
The joined path (/home/ubuntu/app/custom_templates/FooCompany/factors.html) is located outside of the base path component (/home/ubuntu/app/static/media)
What can I do to prevent this error? Is there some best practice approach to my problem or do I have to go for some workaround like setting one of m y TEMPLATE_DIRS to /home/ubuntu/app/static/media/custom_templates. Maybe this is not even a workaround and legit practice.. I don't know really know.. Help is appreciated a lot!
You cannot use FileField to upload files outside of MEDIA_ROOT. That's an important security measure.
You could set TEMPLATE_DIRS to something inside MEDIA_ROOT and most likely this would work, but this makes my cringe really hard. That would essentially gave the users an ability to overwrite any template for any page on the site.
You don't have to save those templates as HTML files to use them as Django templates. You can save them in a database and render them directly from string:
from django.template import engines
from django.http import HttpResponse
# Get the template from database
template_from_db = YourCustomTemplateModel.objects.get(name='homepage')
template_string = template_from_db.content
# Create a django Template object
template = engines['django'].from_string(template_string)
# Render the template to a string
context = {'foo': 'bar'}
page_content = template.render(context=context)
# Send page to a the browser
return HttpResponse(page_content)
You should however think really hard about the security implications of doing this in general. Are you really comfortable with template creators being able to set arbitrary JavaScript on your domain (think cross-site scripting vulnerability)? What about calling arbitrary methods (or at least the ones not having any arguments) and accessing arbitrary arguments on objects you pass in the context dictionary?

Django not looking in the correct place for jinja templates?

I am following this thread here... How to use jinja2 as a templating engine in Django 1.8
I can't seem to find any solid docs on switching to jinja2 templates and how to setup django for it. All the docs seem to have some gaps, or I am missing somehting really obvious. Anyway, I set everything up just like the thread above, except when I try to go somewhere where the template would be loaded I get...
TemplateDoesNotExist
Django tried loading these templates, in this order:
...
But it does not list any of my jinja/ template directories that I specified. Why would this be?
EDIT ADDING TRACE AND SETTINGS:
TEMPLATES = (
{
'BACKEND': 'askbot.skins.template_backends.AskbotSkinTemplates',
},
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [os.path.join(PROJECT_ROOT, 'templates/jinja2')],
'APP_DIRS': True,
'OPTIONS': {'environment': 'myproject.jinja-import.Environment',},
},
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(PROJECT_ROOT, 'templates',),
],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.core.context_processors.request',
'django.contrib.auth.context_processors.auth',
]
}
},
)
Traceback:
File "/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/Django-1.8.8-py2.7.egg/django/core/handlers/base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/jeff/Django/langalang-askbot/langalang/main/views.py" in page
71. context_instance=RequestContext(request, context))
File "/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/Django-1.8.8-py2.7.egg/django/shortcuts.py" in render
89. using=using)
File "/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/Django-1.8.8-py2.7.egg/django/template/loader.py" in render_to_string
137. raise TemplateDoesNotExist(template_name)
Exception Type: TemplateDoesNotExist at /ko/
Exception Value: main/page.html
Template Loader Error:
Django tried loading these templates, in this order:
Using loader django.template.loaders.filesystem.Loader:
/home/jeff/Django/langalang-askbot/langalang/templates/main/page.html (File does not exist)
Using loader django.template.loaders.app_directories.Loader:
/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/Django-1.8.8-py2.7.egg/django/contrib/auth/templates/main/page.html (File does not exist)
/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/Django-1.8.8-py2.7.egg/django/contrib/admin/templates/main/page.html (File does not exist)
/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/Django-1.8.8-py2.7.egg/django/contrib/sitemaps/templates/main/page.html (File does not exist)
/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/django_compressor-1.5-py2.7.egg/compressor/templates/main/page.html (File does not exist)
/home/jeff/Django/langalang-askbot/langalang/askbot-dev/askbot/templates/main/page.html (File does not exist)
/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/django_robots-1.1-py2.7.egg/robots/templates/main/page.html (File does not exist)
/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/django_celery-3.1.17-py2.7.egg/djcelery/templates/main/page.html (File does not exist)
/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/django_tinymce-1.5.3-py2.7.egg/tinymce/templates/main/page.html (File does not exist)
/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/django_recaptcha-1.0.5-py2.7.egg/captcha/templates/main/page.html (File does not exist)
/home/jeff/Django/langalang-askbot/venv/local/lib/python2.7/site-packages/django_avatar-2.2.1-py2.7.egg/avatar/templates/main/page.html (File does not exist)
view that is loading the template:
def page(request, page_title='home'):
context = {
'page_title': page_title
}
if page_title == 'home':
#This query pulls the language instructions objects and then orders it alphabetically by the 'full_title' field
language_pairs = LangPairInstruction.objects.filter(active=True).order_by('full_title')
context['language_pairs'] = language_pairs
elif page_title == 'contact':
form_class = ContactForm(initial={'subject': _('Subject'), 'name': _('Name'), 'email': _('Email'), 'content': _('Content')})
context['ContactForm'] = form_class
elif page_title == 'about':
pass
else:
raise Http404
return render(
request,
'main/page.html',
context_instance=RequestContext(request, context))