Django, Template not found - python

I'm trying to render this HTML File (An Home page) And I get an error that template is not found.
#views.py
from django.shortcuts import render
def index(request):
"""Homepage"""
return render(request,'templates/index.html')
from django.contrib import admin
from django.urls import path, include
from . import views
urlpatterns = [
path('', views.index, name='Home'),
]
error:
TemplateDoesNotExist at /
templates/index.html
and this just loads a blank page:
from django.shortcuts import render
def index(request):
"""Homepage"""
return render(request, 'index.html')
My HTML File
I'm guessing maybe some kind of link is missing here.
I've also added 'os.path.join(BASE_DIR,"templates")' to DIRS and setting and the page is still blank.
<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Home.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<title>Triangulation Calculator</title>
</head>
<body>
<!-- Navigation -->
<nav class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
<div class="container">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarResponsive" aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ml-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home
<span class="sr-only">(current)</span>
</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Three Positions Triangulation</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Second </a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Add Known Location</a>
</li>
</ul>
</div>
</div>
</nav>
<section class="py-5 text-center">
<div class="container">
<h2 class="text-center">Triangulation Calculator</h2>
<p class="text-muted mb-5 text-center">There's three Features here, below, you'll find explaintion for each.</p>
<div class="row">
<div class="col-sm-6 col-lg-4 mb-3">
<svg class="lnr text-primary services-icon">
<use xlink:href="#lnr-magic-wand"></use>
</svg>
<h6>Three Positions Triangulation</h6>
<p class="text-muted">Naming is All, Choose a grate name for your mission so you can come back and open that map whenever you want.
You input the latitude and longitude for GDT 1, GDT 2 and the location of the UAV, also, we need the
elevation of the uav above sea level, where do you get that data?
Thank God for Google.
go to google maps, when you press a location on the map you can the coordinates as we need them, in the following format:
31.4531,35.56243.
first is latitude and longitude, copy the values to calculator.
done?
press POST
the page will refresh and you'll see all your data.
go to the address line and add the mission name to the and of the line.
KABLAM!
Your map will open.</p>
</div>
<div class="col-sm-6 col-lg-4 mb-3">
<svg class="lnr text-primary services-icon">
<use xlink:href="#lnr-heart"></use>
</svg>
<h6>Second GDT options</h6>
<p class="text-muted">Second option works a lot the same: Input your mission name and the data for GDT 1 and the UAV, and choose the area of the mission.
and the rest is the same.
How does the map work here?
if you hover your mouse over one of the numbers you'll see the boundaries of that triangulation, the more you zoom in,
the more detailed it gets.</p>
</div>
<div class="col-sm-6 col-lg-4 mb-3">
<svg class="lnr text-primary services-icon">
<use xlink:href="#lnr-rocket"></use>
</svg>
<h6>Add Location Info to the DataBase</h6>
<p class="text-muted">Here you input a base,outpost,mountain or just every location you ever put a GDT in.
choose the area where that position lies.
and every time someone will use the second option, we'll automatically add those positions to the map.</p>
</div>
</div>
</div>
</div>
</section>
</body>
</html>

You have to create templates folder on same level of app not in the app, and set TEMPLATES variable in settings.py
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',
],
},
},
]
Now, you can add index.html in templates folder or you can add index.html file in an appropriate folder and add that folder in the templates folder. Folder structure is like below...
app_1
|
|
app_2
|
|
templates
|
|__index.html

Check whether you have added the template_dir, if not add this in your settings.py below the BASE_DIR
TEMPLATE_DIR = os.path.join(BASE_DIR,'templates')
and find templates and dirs as a dictionary file in the settings.py, add this
DIRS = [TEMPLATE_DIR,]
or directly you can add in DIRS like this
DIRS = [os.path.join(BASE_DIR,'templates')]
and make sure the directory name is templates not template according to my answer

Related

How to render common things in footer.html in Django

I have set up Django templates, which include index.html, header.html and footer.html.
In footer.html, I want to set dynamically a phone number, email and address. I can see I can pass it through context from views.py, but footer.html will included in all the templates, so I will need to pass it in every function in views.py, which is not good.
So what I want is to create one common function and I want to call it from footer.html. Is that the right way to do this? Or if you have any other idea, then please let me know how to do that.
views.py:
def index(request):
portal_contact_email = preferences.MyPreferences.portal_contact_email
context = {'portal_contact_email': portal_contact_email,}
return render(request, 'mysite/index.html', context)
footer.html:
<footer class="bg-dark footer-section">
<div class="section">
<div class="container">
<div class="row">
<div class="col-md-4">
<h5 class="text-light">Email</h5>
<p class="text-white paragraph-lg font-secondary">{{ portal_contact_email }} </p>
</div>
<div class="col-md-4">
<h5 class="text-light">Phone</h5>
<p class="text-white paragraph-lg font-secondary"></p>
</div>
<div class="col-md-4">
<h5 class="text-light">Address</h5>
<p class="text-white paragraph-lg font-secondary"></p>
</div>
</div>
</div>
</div>
<div class="border-top text-center border-dark py-5">
<p class="mb-0 text-light">Copyright #<script>
var CurrentYear = new Date().getFullYear()
document.write(CurrentYear)
</script>
{# a theme by themefisher.com#}
</p>
</div>
</footer>
For this purpose you could create a custom ContextProcessor.
According to the docs, ContextProcessors
take a request object as their argument and return a dictionary of items to be merged into the context
A custom ContextProcessor in your case could look like this:
def footer_data(request):
return {'phone_number': 'xyz', ...}
Then append it to your settings.py so it is actually being used:
TEMPLATES = [
{
...
'OPTIONS': {
'context_processors': [
'myapp.my_context_processors.footer_data',
...
And in your templates you can access these variables simply with {{ phone_numer }}.

passing a parameter from html page url mapping to the views in django

front.html
<div class="row">
<a href="{% url 'emp_pay_list' Information_technology %}">
<div class="col-md-6 col-sm-6 col-lg-3">
<div class="dash-widget clearfix card-box" style="height: 200px;">
<span class="dash-widget-icon"><i class="fa fa-cubes" aria-hidden="true"></i></span>
<div class="dash-widget-info">
<h3>20</h3>
<span>Information Technology</span>
</div>
</div>
</div>
</a>
<a href="{% url 'emp_pay_list' sales %}">
<div class="col-md-6 col-sm-6 col-lg-3">
<div class="dash-widget clearfix card-box" style="height: 200px;">
<span class="dash-widget-icon"><i class="fa fa-users" aria-hidden="true"></i></span>
<div class="dash-widget-info">
<h3>7</h3>
<span>Sales Team</span>
</div>
</div>
</div>
</a>
</div>
The above code is the front end part HTML here I want to pass a parameter into the urls.py by clicking a box and depends on the parameter which we pass the data should be fetched.
urls.py
url(r'^list_of_employees/<string>/$', views.Pay_slip_list , name='emp_pay_list'),
This is the code which I am using in urls.py to pass parameter.
views.py
def Pay_slip_list(request, department):
hello = employees.objects.select_related('employee_name', 'employee_auth').filter(department=department)
return render(request, 'hr/emp_pay_list.html', {'hello': hello})
And this is the views.py part where I am fetching data from the database based on the string/parameter passed after clicking the box.
Your URL pattern must look like
from django.urls import path, re_path
path('list_of_employees/<str:department>/', views.Pay_slip_list , name='emp_pay_list'),
or use re_path
re_path(r'^list_of_employees/(?P<department>[\w\-]+)/$', views.Pay_slip_list , name='emp_pay_list')
use path instead of url for Django version >= 2.0, or use re_path for complex patterns, re_path is same as url method in lower versions

Links that I have in 'navbar' overlaps each other:/

Hello everyone:) Links that I have in 'navbar' overlaps each other when I make a transition into another link. For instance, I have a navbar menu with four different links (home, catalog, distributors and contacts) and 'home' is a base webpage. I.e when I make a transition from the base webpage 'http://127.0.0.1:8000/' to catalog I get this http://127.0.0.1:8000/catalog (all right) but then I make a transition into section 'distributors' and then I get this 'http://127.0.0.1:8000/catalog/distributors (and it's not normal) How to rectify this?
My url patterns seems right :/
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^catalog/$', views.catalog, name='catalog'),
url(r'^distributors/$', views.distributors, name='distributors'),
url(r'^contacts/$', views.contacts, name='Contacts'),
]
template:
<div class="header">
<div id="inner">
<div class="col">
<div class="inner">
<div class="image"><p>HOME</p></div>
<div class="filter1"></div>
<div class="filter2"></div>
<div class="txt">
<p>We greet you on the main</p>
<p>page of our website!</p>
</div>
</div>
</div>
<div class="col">
<div class="inner">
<div class="image"><p>CATALOG</p></div>
<div class="filter1"></div>
<div class="filter2"></div>
<div class="txt">
<p>Browse through our catalog</p>
<p>and select the good just for you.</p>
</div>
</div>
</div>
<div class="col">
<div class="inner">
<div class="image"><p>DISTRIBUTORS</p></div>
<div class="filter1"></div>
<div class="filter2"></div>
<div class="txt">
<p>We are currently expanding our</p>
<p>distributor network into new markets.</p>
</div>
</div>
</div>
<div class="col">
<div class="inner">
<div class="image"><p>CONTACTS</p></div>
<div class="filter1"></div>
<div class="filter2"></div>
<div class="txt">
<p>You can always communicate with us</p>
<p>using section "Contacts". </p>
</div>
</div>
</div>
</div>
</div>
views:
def home(request):
products_images = ProductImage.objects.filter(is_active=True, is_main=True, product__is_active=True)
products_images_with = products_images.filter(product__category__id=1)
products_images_without = products_images.filter(product__category__id=2)
return render(request, 'landing/home.html', locals())
def catalog(request):
products_images = ProductImage.objects.filter(is_active=True, is_main=True, product__is_active=True)
return render(request, 'landing/catalog.html', locals())
def distributors(request):
return render(request, 'landing/distributors.html', locals())
def contacts(request):
return render(request, 'landing/Contacts.html', locals())
Can someone help me with this problem? Django version 1.11.2
As #David D. answered, you should use the method of url building as it provides you flexibility.
But, if for some reason you want that absolute URLs should be specified in href, then while using absolute urls the above problem can be solved by prepending a forward slash to each url name when assigning to href.
So your new urls should look like :
CATALOG
DISTRIBUTORS
CONTACTS
The reason it works is that / represents root of website, so using '/' routes you to the root and using '/catalog' routes you to the catalog page directly from the root.
The problem is the way you use links in your Django templates.
Take a look to: https://docs.djangoproject.com/en/2.0/ref/templates/builtins/#url
You have to use a {% url 'url-name-here' %} sothat Django will build url by itself.
For example, in your case:
<div class="image"><p>CATALOG</p></div>
This way:
it's a lot easier for you, you just provide the url name and let Django generated the real url.
you don't repeat yourself; if you want to change the path of the url, you only need to do it one time in urls.py.

Send data from django views to angularjs controller

I am trying to send data from django views.py file to angularjs controller.js file but unable to send it.
The problem is this that I am unable to send data from views file to controller. And when I run my code then the value {%steps%} doesn't change to the value I have assigned in views file.
I don't want to use Django rest framework for doing this.
Is there any other way of achieving this? If yes, then please help me out.
views.py:
from django.shortcuts import render
from django.conf import settings
from user_data.models import GetData
import json
def home(req):
return render(req, 'index.html')
def userData(req):
if req.method == 'GET':
user_data = GetData().getAllData()
context_dict = {'user_data1' : json.dumps(user_data[0]),
'user_data2' : json.dumps(user_data[1]),
'user_steps' : json.dumps(2000)}
return render(req, 'index.html', context_dict)
controller.js :
'use strict';
MetronicApp.controller('DashboardController', function($rootScope, $scope, $http, $timeout) {
$scope.$on('$viewContentLoaded', function() {
// initialize core components
Metronic.initAjax();
});
$scope.steps = {{user_steps|safe}};
});
html file:-
<div ng-controller="DashboardController" class="margin-top-10">
<div class="row ">
<div class="col-md-12 col-sm-12">
<div class="portlet light ">
<div class="portlet-title">
<div class="caption">
<i class="icon-cursor font-purple-intense hide"></i>
<span class="caption-subject font-purple-intense bold uppercase">Tracker Report</span>
</div>
<div class="actions">
<a href="javascript:;" class="btn btn-sm btn-circle btn-default easy-pie-chart-reload">
<i class="fa fa-repeat"></i> Reload </a>
</div>
</div>
<div class="portlet-body">
<div class="row">
<div class="col-md-3">
<div class="easy-pie-chart">
<div class="number transactions" data-percent="55">
<span>{$ steps $}</span>
</div>
<!-- <a class="title" href="#"> -->
Steps <!-- <i class="icon-arrow-right"></i> -->
</a>
</div>
</div>
<div class="margin-bottom-10 visible-sm">
</div>
<div class="col-md-3">
<div class="easy-pie-chart">
<div class="number visits" data-percent="85">
<span>
+85 </span>
%
</div>
<!-- <a class="title" href="#"> -->
Sleep<!-- <i class="icon-arrow-right"></i> -->
</a>
</div>
</div>
<div class="margin-bottom-10 visible-sm">
</div>
<div class="col-md-3">
<div class="easy-pie-chart">
<div class="number bounce" data-percent="46">
<span>
+46 </span>
%
</div>
<!-- <a class="title" href="#"> -->
Calories <!-- <i class="icon-arrow-right"></i> -->
</a>
</div>
</div>
<div class="margin-bottom-10 visible-sm">
</div>
<div class="col-md-3">
<div class="easy-pie-chart">
<div class="number bounce" data-percent="32">
<span>
+32 </span>
%
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
This is basically what I have done in one of my major django projects (but I am not 100% sure, whether this is or this ain't what you are looking for, as an answer).
So, instead of views.py, I have made a custom.py file in which I make custom APIs and call them (using urlpatterns) in the urls.py of my django app. And I have another set of APIs for which I am using django rest framework, for which I make viewsets rather than simple views. Just in case, you are interested, you might like reading this SO link.
But since, you specifically mentioned that you don't want to use django rest frameworks, I will give you an example of the custom.py file, as mentioned above.
Below you will find a sample of an API defined in a custom.py,
#api_view(['GET'])
def get_user_details(request):
"""
API View that gives a user detail
---
parameters:
- name: email
description: The email of the user based on which his/her information has been extracted
required: true
type: string
responseMessages:
- code: 400
message: Email required as GET parameters.
message: User not found.
- code: 200
mesage: User details sent successfully
consumes:
- application/json
- application/xml
produces:
- application/json
- application/xml
"""
email = request.query_params.get('email', None)
if email is None:
return HttpResponseBadRequest("Email required as GET parameters.")
try:
user = User.objects.get(username=email)
except User.DoesNotExist:
return HttpResponseBadRequest("User not found.")
response_data = {'id': user.id, 'first_name': user.first_name, 'last_name': user.last_name,}
return HttpResponse(json.dumps(response_data), content_type="application/json")
And subsequently, the urls.py in my django app looks like:
urlpatterns = router.urls
urlpatterns = urlpatterns + [
url(r'get_user_details/', get_user_details),
]
My controller would look something like this:
CheckEmail : function (current) {
return $http({
method: 'GET',
url: baseAPI + 'admin/get_user_details/',
params: {email: current},
})
},
And then subsequently, you may be able to render the variable you wish to print in your html file using handles.
Hope, it helps.

Flask w/ Apache & FCGI routing problems

So I've been working w/ Flask & Bootstrap on an Apache Server. I've gotten it to the point where I can access the app & render the "first" or "main" template w/ the following route:
from view.py:
#app.route('/')
def fn_home():
return render_template("main.html")
Unfortunately, every attempt to route to another webpage/function from main.html fails. I'm using the "url_for" function in the navbar list href, attempting to get flask to supply the xls-upload.html webpage to Apache.
from main.html:
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>Upload Spreadsheets </li>
from view.py:
#app.route('/upload')
def upload():
return render_template("xls-upload.html")
It looks like the function is being engaged, since the URL changes to http://myapp/upload, but the html page is NOT rendered/returned by the function - instead I receive a 404 "Not Found". I can't seem to return anything from the function, even return "Hello World".
It "seems" like Apache is really trying to resolve the http://myapp/upload path, rather than having a socket opened up to the Flask application through which the html is then sent. I'm not sure if this is a FCGI problem, if I'm missing a relative/absolute path issue, misunderstanding how Flask works in general, or some combination of all, etc.
I'm new to Flask so I'm hoping that someone could help me along the way since I really feel I've come to a dead end.
Thanks in advance!
My flask app is structured as follows:
var/www/cgi-bin/myapp/ (root dir)
start.fcgi
view.py (the flask routing/app file)
static (dir)
bootstrap files
templates (dir)
main.html
xls-upload.html
Here are my applicable files:
1) /etc/httpd/conf.d/myapp:
<VirtualHost *:80>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/cgi-bin/myapp/static/
ServerName myapp
Alias /static/ /var/www/cgi-bin/myapp/static/
ScriptAlias / /var/www/cgi-bin/myapp/start.fcgi
<Directory "var/www/cgi-bin/myapp">
AllowOverride None
Order allow,deny
Allow from all
AuthType Basic
AuthUserFile /etc/httpd/.htpasswd
AuthName 'Enter Password'
Require valid-user
</Directory>
</VirtualHost>
2) /var/www/cgi-bin/myapp/start.fcgi:
#!/usr/bin/python
# IMPORTS:
from flup.server.fcgi import WSGIServer
from view import app
if __name__ == '__main__':
WSGIServer(app).run()
3) /var/www/cgi-bin/myapp/view.py:
#!/usr/bin/python
# IMPORTS:
import os
from flask import Flask, render_template, url_for, request, session, redirect
from werkzeug import secure_filename
# STATIC VARIABLES
UPLOAD_FOLDER = 'var/www/cgi-bin/myapp/xls-dir'
ALLOWED_EXTENSIONS = set(['xls'])
## flask:
app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# FUNCTIONS
def fn_allowed_file(filename):
return '.' in filename and \
filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
#app.route('/')
def fn_home():
return render_template("main.html")
#app.route('/upload')
def upload():
return render_template("xls-upload.html")
#return "HI there"
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')
4) /var/www/cgi-bin/myapp/templates/main.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>ALG Tools HOME</title>
<!-- Bootstrap -->
<link href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}" rel="stylesheet">
</head>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">ALG Tool - HOME</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>Upload Spreadsheets </li>
<li>Download Spreadsheets</li>
<li>Generate Configs</li>
</ul>
</div>
</div>
</nav>
<body>
<h2>ALG stuff</h2>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{{ url_for('static', filename = 'js/bootstrap.min.js') }}"></script>
</body>
</html>
5) /var/www/cgi-bin/myapp/templates/xls-upload.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>ALG XLS Upload</title>
<!-- Bootstrap -->
<link href="{{ url_for('static', filename = 'css/bootstrap.min.css') }}" rel="stylesheet">
</head>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">ALG Tool - HOME</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>Upload Spreadsheets </li>
<li>Download Spreadsheets</li>
<li>Generate Configs</li>
</ul>
</div>
</div>
</nav>
<body>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="{{ url_for('static', filename = 'js/bootstrap.min.js') }}"></script>
</body>
</html>
FCGI isn't really a recommended way to serve a Python web app. You should look into one of the many ways of running WSGI.
However, assuming you need to do this for some reason, you have a minor configuration issue which is the cause of your problem; you need a trailing slash on the ScriptAlias path.
ScriptAlias / /var/www/cgi-bin/myapp/start.fcgi/
With this, Apache will pass the full path to the start.fcgi script, instead of replacing it.
Note that even with FCGI, you should not put your app code in cgi-bin. It doesn't need to be there, as it isn't run by the web server like a CGI app. In fact, your code should not even be under /var/www at all.

Categories