Django - Show plot from SQLite database, accessed by form - django

So I have a page written using Django where someone can enter information into a form, and on submit it accesses a SQLite database to retrieve the queried information. So far I have gotten this far, but I am not able to create and show a plot below the form on the page.
I have tried different packages: ChartIt, Graphos and nvd3. Either way I get an error, likely because I don't understand the full details of the coding in Django.
Below is my try at creating a plot with nvd3. When I try to load the page I get the error:
Exception Value: Invalid block tag: 'load_chart', expected 'elif', 'else' or 'endif'
at the line in my viewrun.html where I assume I load in the nvd3:
{% load_chart charttype chartdata "linewithfocuschart_container" True "%d %b %Y %H" %}
Here are the files I use. Thank you for any help!
views.py
def createplot(molecules, chemrun_id, database='laminar_idl.test.db'):
conn, status_db = conn_to_db(database)
if status_db and not molecules==None:
time, x, y, abunds, status_fetch = get_one_species_all_times(conn, str(molecules))
chartdata = {'x': time,
'name1': molecules, 'y1': abunds}
charttype = "lineWithFocusChart"
data = {
'charttype': charttype,
'chartdata': chartdata
}
return data
return None
#login_required
def run(request, chemrun_id=1, molecule=None):
if request.POST:
form = MolChoiceForm(request.POST)
if form.is_valid():
form.save()
molecule = form.cleaned_data['molecule']
return HttpResponseRedirect('/chemrun/run/'+chemrun_id+'/'+molecule+'/')
else:
form = MolChoiceForm()
args = {}
args.update(csrf(request))
args['form'] = form
args['chemrun'] = ChemRun.objects.get(id=chemrun_id)
if not molecule is None:
args['molecule'] = molecule
plotdata = createplot(molecule, chemrun_id)
args['plotdata'] = plotdata
return render_to_response('interface/viewrun.html', args, context_instance=RequestContext(request))
viewrun.html:
{% extends "interface/base.html" %}
{% block content %}
<article>
{% if user.is_authenticated %}
<header>
<p><font size="+2">Chemical run: <i>{{run.title}}</i> (<b>ID #{{chemrun.id}}</b>)</font></p>
{% load_chart charttype chartdata "linewithfocuschart_container" True "%d %b %Y %H" %}
</header>
<section>
<p>Outputs written for {{chemrun.n_times}} time steps between {{chemrun.times_min}} and {{chemrun.times_max}} years</p>
<p>Temperature: <b>{{chemrun.temperature}}</p>
<p>Density: <b>{{chemrun.density}}</p>
<hr>
<form action='/chemrun/run/{{chemrun.id}}/' method='post' style="display: inline-block;">{% csrf_token %}
{{form}}
<input type="submit" name="submit" value="Plot">
</form>
</section>
{% else %}
<h2>No data available because you are not logged in.
{% endif %}
{% endblock %}
base.html:
{% load staticfiles %}
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="apple-touch-icon" href="apple-touch-icon.png">
<link rel="stylesheet" href="{% static 'css/normalize.min.css' %}">
<link rel="stylesheet" href="{% static 'css/main.css' %}">
<link media="all" href="{% static 'nvd3/src/nv.d3.css' %}" type="text/css" rel="stylesheet" />
<script type="text/javascript" src='{% static 'd3/d3.min.js' %}'></script>
<script type="text/javascript" src='{% static 'nvd3/nv.d3.min.js' %}'></script>
<!--<script src="js/vendor/modernizr-2.8.3-respond-1.4.2.min.js"></script>-->
<title>Chemicalizer</title>
</head>
<body>
<div class="header-container">
<header class="wrapper clearfix">
<h1 class="title"><b><a href='/'>Chemicalizer</a></b> </h1>
<!--<h2 class="subtitle">- You need it!</h2>-->
<nav>
<ul>
{% if user.is_authenticated %}
{% if user.is_superuser %}
<li>Admin</li>
<li>All Models</li>
{% else %}
<li>Start model</li>
<li>My Models</li>
{% endif %}
<li>Logout</li>
{% else %}
<li>Login</li>
<li>Register</li>
<li>Contact</li>
{% endif %}
</ul>
</nav>
</header>
</div>
<div class="main-container">
<div class="main wrapper clearfix">
{% block content %}
{% endblock %}
</div> <!-- #main -->
</div> <!-- #main-container -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="js/vendor/jquery-1.11.2.min.js"><\/script>')</script>
<!--<script src="js/main.js"></script>-->
</body>
</html>

For people in the future fighting the same problem, I was using pages that did not explain all steps for getting nvd3 to work (or they were maybe outdated).
Here are the steps to follow to install it and get it working:
1) Install django-nvd3 using pip install django-nvd3
2) Since this is dependent on python-nvd3, we need to install bower using npm install -g bower. (If you don't have npm, just install it with macports, or any other way you like.)
3) Next, install django-bower with the command pip install django-bower
4) Then run bower install nvd3 which will also install the dependency d3
5) Edit your view.py to something like this, this example is for a lineChart:
charttype = "lineChart"
chartcontainer = 'linechart_container' # container name
data = {
'charttype': charttype,
'chartdata': chartdata,
'chartcontainer': chartcontainer,
'extra': {
'x_is_date': False,
'x_axis_format': '',
'tag_script_js': True,
'jquery_on_ready': True,
'chart_attr': {
'xScale':'(d3.scale.log())', #for logscale on x-axis
'yScale':'(d3.scale.log())', #for logscale on y-axis
'xAxis.axisLabel':'"Time, yrs"',
'yAxis.axisLabel':'"n(X)/n(H)"',
}
}
}
return data
6) Update your settings.py with the following:
BOWER_COMPONENTS_ROOT = BASE_DIR
BOWER_PATH = '/usr/local/bin/bower'
BOWER_INSTALLED_APPS = (
'd3',
'nvd3',
)
and also add 'djangobower.finders.BowerFinder', to your STATICFILES_FINDERS = (
7) Now your html code has to include these (in the head for example):
<link media="all" href="{% static 'nvd3/src/nv.d3.css' %}" type="text/css" rel="stylesheet" />
<script type="text/javascript" src='{% static 'd3/d3.min.js' %}'></script>
<script type="text/javascript" src='{% static 'nvd3/nv.d3.min.js' %}'></script>
And somewhere in your main body:
{% include_chart_jscss %}
{% load_chart charttype chartdata chartcontainer extra %}
Finally, for wherever you want the plot to appear:
{% include_container chartcontainer %}
This worked for me. If anyone more knowledgeable about this finds any mistakes, please help me correct them :)

Related

How to place Bokeh widgets precisely on an html page

I am struggling to place Bokeh widgets precisely where I want them on an html page built with Django. For example my views.py look like this:
from bokeh.io import show
from bokeh.layouts import column, row
from bokeh.models import CustomJS, TextInput
from bokeh.plotting import figure
fig = figure(title='title')
fig.line(x=[1,2,3], y=[1,2,3])
text_input = TextInput(title="Add graph title", value='')
text_input.js_on_change('value', CustomJS(
args={'title': fig.title, 'text_input': text_input},
code="title.text = text_input.value"
))
widgets_layout = column(text_input)
figures_layout = row(fig)
#show(row(widgets_layout, fig))
# Set up page layout
page_layout = row(widgets_layout, figures_layout)
script, div = components(page_layout)
return render_to_response('app/test.html', {'script':script, 'div':div})
and my html page (test.html) look like this:
<!--Test page-->
{% extends "base.html" %}
{% load static %}
{% load bootstrap4 %}
{% load i18n %}
{% block content %}
<!--Bokeh-->
<link href="http://cdn.bokeh.org/bokeh/release/bokeh-1.3.4.min.css" rel="stylesheet" type="text/css">
<link href="http://cdn.bokeh.org/bokeh/release/bokeh-widgets-1.3.4.min.css" rel="stylesheet" type="text/css">
<link href="http://cdn.bokeh.org/bokeh/release/bokeh-tables-1.3.4.min.css" rel="stylesheet" type="text/css">
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-1.3.4.min.js"></script>
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-widgets-1.3.4.min.js"></script>
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-tables-1.3.4.min.js"></script>
<!--Figure-->
<div class='col-lg'>
<div class='card-lg bg-light' id='maincontent'>
<h2> {% trans "Test" %}</h2>
<hr>
<div>
{{ div | safe }}
{{ script | safe }}
</div>
</div>
</div>
<br>
{% endblock content %}
Now, how can I move the little widget (text_input) to a precise position ? Any position will do, I just want to be able to place it pretty much wherever I want.
Thank you,
You could apply for example spacing (which can also be negative) on the Row and/or on the Column like this:
widgets_layout = column(Div(), row(Div(), text_input, spacing=300), spacing=300)

how to send data from the view to the header or the navigationBar

I have a Django website that has a navigation bar where I need to display the user and the group that the user belongs to in the navigation bar in order to make this information visible on all pages.
Until now I am able to send these data items to a specific page but not to the header.
views.py
def home(request):
#print(User.groups.get())
print(request.session.keys())
if request.session.has_key('theUser'):
authed=request.session['theUser']
if request.session.has_key('group'):
sections=request.session['group']
return render(request,'./mainpage.html',{'sections':sections,'authed':authed})
else:
authed=None
else:
authed=None
return render(request,'./Login.html',{'authed':authed})
Where I am sending {'sections':sections,'authed':authed}
to mainpage.html
mainpage.html
<div id='left-column-Input' class="formInput" include="select()">
{{user.get_username}}|{{sections}}
What I need is to send the data to the header or the base file.
base.html
<!DOCTYPE html>
{% load static %}
<html>
<head>
<script type="text/javascript" src="{% static '/js/jquery-3.1.1.min.js' %}"></script>
<link rel= "icon" type= "image/png" href="{% static 'img/logo_title/icon-AddressBar.png'%}">
<link rel="stylesheet" type="text/css" href="{% static '/css/search.css'%}">
<link rel="stylesheet" type="text/css" href="{% static '/css/style.css'%}">
</head>
<body>
<img class="logoMM" src="{% static 'img/logoMM.png' %}" alt="Smiley face" />
<!-- <div class="wrap"> -->
<div class="wrap search Horizontal-scale">
<!-- <div class="Horizontal-scale"> -->
<button type="submit" class="searchButton">
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="search" role="img" viewBox="0 -20 530 530"><path fill="currentColor" d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"></path></svg>
</button>
<input type="text" class="searchTerm" placeholder="search">
<!-- <div class="Horizontal-scale"> -->
<label for="toggle">☰</label>
<input type="checkbox" id="toggle"/>
<div id="container" class="Horizontal-menu">
<ul>
<li>main</li>
<li>search</li>
{% if authed is not None %}
<li>logout</li>
<script type="text/javascript">
$(function(){
$('#logMeOut').on('click',function(){
$.ajax({
url:'/usr/logMeOut',
method:'POST',
headers:{
'X-CSRFToken':'{{csrf_token}}'
}
}).done(function(msg){
console.log(msg)
document.location='/'
}).fail(function(err){
alert(err)
})
})
})
</script>
{% endif %} </th>
</ul>
</div>
</body>
{% block body %}
{% endblock %}
</html>

Not able to parse the remainder in django template

<html>
<head>
<title>{{ songname }}</title>
<meta charset="UTF-8">
{% load static %}
</head>
<body>
<center><h1>MUOSIC</h1></center>
<hr>
<audio controls>
<source src="{% static {{ songname }} %}" type="audio/mpeg">
</audio>
<hr>
</body>
Here songname is the name of the song which i want to play.All the static files are in the static directory.From the view function the above template is called using render_to_response function.So please can anyone explain the reason for this problem.
You can't nest template variables like that. Assuming that your songname is the actual name of the file and the file is in the root of your STATIC_ROOT, you simply do:
{% static songname %}

django static files

I have in my urls.py line:
if settings.DEBUG==True:
urlpatterns += patterns('',
(r'^static/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_DOC_ROOT})
)
In my settings file something like this:
STATIC_DOC_ROOT = os.path.join(os.path.dirname(__file__),'static').replace('\\','/')
And when I go to / in my page everything work just great. And when I click a link from / to anther page I don't have CSS applied because of 404 error. He tries to load a CSS file from that URL.
http://localhost:8000/show/sth/static/style.css
Here is my urls.py for this method
(r'^show/(?P<subject>[^/]+)/(?P<title>[^/]+)$','show'),
I have url /links and css works just in this one template it does not work. It seems that these parameters messing something up. Any suggestions why this fails?
Here is my template code:
{% extends "szkielet.html" %}
{% block tresc %}
<div id="content">
<div class="post">
<h2 class="title">{{ notatka.tytul }}</h2>
<p class="meta"><span class="author">{{ notatka.user.name }}</span> <span class="date">July 07, 2010</span> <span class="links">Comments</span></p>
<div class="entry">
<p>{{ notatka.tresc }}</p>
</div>
</div>
</div>
{% endblock %}
Szkielet.html - it is my base
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="keywords" content="" />
<meta name="description" content="" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>Perfect Blemish by Free CSS Templates</title>
<link href="{{ MEDIA_URL }}style.css" rel="stylesheet" type="text/css" media="screen" />
</head>
<body>
Here is part responsible for CSS it is only one style sheet .
URL's could potentially be set to override the static url path but that's not the case here! So your URL conf doesn't have anything to do with this.
The core problem is that your template is rendering an incorrect URL: http://localhost:8000/show/sth/static/style.css should be http://localhost:8000/static/style.css correct?
Show us your template since that seems to be the problem. Sounds to me like you just have a relative URL set for your CSS instead of absolute or /static/style.css
What is your {{ media_url }}? It's supposed to be absolute, and begin with a /

How do I retain the whitespace in templates' blocks?

I'm using SHPAML (HAML for python) for Django, however, I'm facing problems converting SHPAML -> HTML because of whitespace issues when overriding some blocks, heres an example:
In skeleton.shpaml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>{{ title }}</title>
{% comment %}
<link rel="shortcut icon" href="/static/images/favicon.ico" type="image/x-icon"/>
{% endcomment %}
{% if css_list %}
{% for css in css_list %}
<link type="text/css" rel="stylesheet" href="{{css_relative}}{{ css }}">
{% endfor %}
{% endif %}
{% if js_list %}
{% for js in js_list %}
<script type="text/javascript" src="{{js_relative}}{{ js }}">
</script>
{% endfor %}
{% endif %}
{% if no_cache %}
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
{% endif %}
</head>
body
#nonFooter
#content
{% block header %} {% endblock %}
#maincontent
{% block content %} {% endblock %}
#footer
</html>
In index.shpaml:
{% extends "includes/skeleton.shpaml" %}
{% block content %}
asd
.test
.test2 | meh
{% endblock %}
In the end, my output is this:
!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Home | Zineified</title>
<link type="text/css" rel="stylesheet" href="/media/css/base.css">
<script type="text/javascript" src="/media/js/jquery-1.3.2.min.js">
</script>
<script type="text/javascript" src="/media/js/jquery.form.js">
</script>
<script type="text/javascript" src="/media/js/base.js">
</script>
</head>
body
#nonFooter
#content
#maincontent
asd
.test
.test2 | meh
#footer
</html>
As you can see, whitespace is not preserved in the blocks. The next line in index.shpaml goes straight down into the next line in skeleton.shpaml. How can I prevent this and retain whitespace through template extending?
It looks like the SHPAML preprocessor is not getting invoked BEFORE Django. What I typically do is write all my documents in SHPAML with a .shpaml extension, and then I convert them to Django with the .html extension, and then let Django do its magic. So you will want statements like "extends" and "include" to refer to the .html document that has already been preprocessed.
Your base shpaml doc will look something like this:
html
body
#main_page
{% block body %}
{% endblock %}
And then the document that extends it will look something like this:
{% extends 'base.html' %}
{% block body %}
p
This is a paragraph about {{ book }}...
{% endblock %}
And then you want to preprocess them BEFORE Django sees them. I usually preprocess them with a Python script right before doing "manage.py runserver."
from docs:
spaceless
Removes whitespace between HTML tags. This includes tab characters and newlines.
Example usage:
{% spaceless %}
<p>
Foo
</p>
{% endspaceless %}
This example would return this HTML:
<p>Foo</p>
Only space between tags is removed -- not space between tags and text.
You can also remove excess spaces/newlines manually, but that will reduce the readability of the template.
#maincontent
asd
You mean misalignment here? Well, align your index.shpaml accordingly:
{% extends "includes/skeleton.shpaml" %}
{% block content %}
asd
.test
.test2 | meh
{% endblock %}
I've wrote a simple script to recursively explore a directory and find all shpaml files and convert them to *.htm. Thought I'd share it:
#!/usr/bin/env python
#===============================================================================
# Recursively explore this entire directory,
# and convert all *.shpaml files to *.htm files.
#===============================================================================
import shpaml
import os, glob
count = 0
def main():
global count
cwd = os.path.dirname(os.path.abspath(__file__))
convert_and_iterate(cwd)
print("Done. Converted "+str(count)+" SHPAML files.")
def convert_and_iterate(path):
global count
for file in glob.glob(os.path.join(path,'*.shpaml')):
#getting generic name
file_basename = os.path.basename(file)
gen_name = os.path.splitext(file_basename)[0]
#opening shpaml file and converting to html
shpaml_file = open(file)
shpaml_content = shpaml_file.read()
html_content = shpaml.convert_text(shpaml_content)
#writing to *.htm
html_file = open(os.path.join(path,gen_name+".htm"),"w")
html_file.write(html_content)
#incrementing count
count += 1
#transverse into deeper directories
dir_list = os.listdir(path)
for possible_dir in dir_list:
if os.path.isdir(os.path.join(path,possible_dir)):
convert_and_iterate(os.path.join(path,possible_dir))
if __name__ == "__main__":
main()