Display Charts based on year select in django - python

I am using django=3.0.0 as my backend. I have years in my database as a datetimefield and I want to put it as an option for my select button which will change the charts dynamically in chartjs.
Do I have to make a filter for this or is there any other way to put my years in chartjs.
Can anyone guide me how to do this?

Well, here's an example.
# views.py
class SomeView(View):
def get(self, request, *args, **kwargs):
context = {} # put some data here
return render(request, "pathto/jsfile.js", context)
# urls.py
urlpatterns = [
# ...
path("chart/js", views.SomeView.as_view(), name="js"),
# ...
]
# template
<!-- example -->
<div>
<canvas id="chart"></canvas>
<script type="text/javascript" src="{% url 'js' %}"></script>
<div/>
# jsfile.js
var chart = document.getElementById("chart");
{% if some_context %}
// do something
{% endif %}

Related

Best way to connect Django Query results to Chart.js charts?

Can someone advise what is the cleanest/easyest way to connect my query to the Data/Label part of chart.js script?
Thank you in advance.
For example, you can do this in your views.py:
# inside views.py
from django.views.generic import View
from django.shortcuts import render
class YourView(View):
def get(self, request, *args, **kwargs):
context = {} # <- you can add whatever you want in here
# some code...
return render(request, "path/to/js/file", context, content_type="text/javascript")
Inside your urls.py
from django.urls import path, include
from . import views
urlpatterns = [
path("data/js", views.YourView.as_view(), name="somejs"),
# and other urls...
]
Inside your template (html file)
<!-- this is just an example -->
<div>
<canvas id="myChart"></canvas>
<script type="text/javascript" src="{% url 'somejs' %}"></script>
<div/>
Inside your js file, you can do some javascript.
var chart = document.getElementById("myChart");
"{{some_context}}" // you can access to the context
{% if some_context %}
// do something
{% endif %}

In django templates, how to dynamically update header section depending on a customized tag parameters in body section

I am building a Django listing app. to use it, a template should looks like this :
{% load django_listing %}
<html>
<head>
...
{% include "django_listing/header.html" %}
...
</head>
<body>
...
{% render_listing data some_parameters %}
...
{% include "django_listing/footer.html" %}
</body>
</html>
This template is directly used in a TemplateView. It is important to know that the user can define all parameters in the template, the listing is created on-the-fly in the custom render_listing tag thus some_parameters is only known in template side (not known at TemplateView side). The user only gives the data in the TemplateView context.
I want to dynamically declare some CSS and JS depending on the some_parameters values. I succeded to do that for JS in {% include "django_listing/footer.html" %}, but not for CSS because when rendering {% include "django_listing/header.html" %} the listing object has not been created yet.
Do you have an idea how to dynamically declare some CSS depending on the some_parameters ?
May be there is a way to postpone {% include "django_listing/header.html" %} rendering ?
Finally, the solution was to create a template tag for the header that renders the remaining before itself :
class ListingHeaderNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
remaining_output = self.nodelist.render(context)
tpl = template.loader.get_template('django_listing/header.html')
tpl_output = tpl.render(context.flatten())
return f'{tpl_output}\n{remaining_output}'
#register.tag(name="render_listing_header")
def do_listing_header(parser, token):
nodelist = parser.parse()
return ListingHeaderNode(nodelist)
Then I can use it instead of the include :
{% load django_listing %}
<html>
<head>
...
{% render_listing_header %}
...
</head>
<body>
...
{% render_listing data some_parameters %}
...
{% render_listing_footer %}
</body>
</html>

Adding CSS style to table in django with django_tables2

I'm very new to Django. I'm trying to add a CSS style to a table when
{% render_table table %}
is being run.
The code looks as following:
views.py:
def myTable(request):
table = myDataTable.objects.all()
filter = request.GET.get('q')
startDate = request.GET.get('sd')
endDate = request.GET.get('ed')
if mail:
table = table.filter(Q(filter__icontains=filter) &
Q(evaluation_date__range=[startDate, endDate])).distinct()
else:
table = table.filter(Q(evaluation_date__range=[startDate, endDate])).distinct()
table = TableView(table)
RequestConfig(request).configure(table)
return render(request, 'myapp/myTable.html', {'table': table})
tables.py:
class TableView(tables.Table):
class Meta:
model = myDataTable
template = 'django_tables2/bootstrap.html'
myApp.html
{% load staticfiles %}
{% load render_table from django_tables2 %}
....
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">
....
<body>
{% render_table table %}
In project/static/css/ I have a custom style file customstyle.css, but there is no way to make the rendered table use that style.
Could you please help me?
I struggled to get the correct style for a table I was also rendering via:
{% render_table table %}
In your tables.py file you can do as follows to set attributes of the table itself (such as its' class):
class TableView(tables.Table):
class Meta:
attrs = {'class': 'table table-striped table-hover'}
Styling a table generated by django-tables2 is explained in the documentation. You can use the default class attributes, or specify custom ones.
In order to use your custom style sheet customstyle.css (using the classes mentioned above), you must include it into your template. django-tables2 doesn't do that for you, but you can learn how to do that from the django tutorial part 6:
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'polls/style.css' %}" />
You have to adjust names and paths according to the location in your project.

I am using django tables 2 and trying to export my table following the official documentation

I have followed the official documentation of django tables 2 but it is not working I dont know why
views.py
from django.shortcuts import render
from django_tables2 import RequestConfig
from django.template.response import TemplateResponse
from .models import Customer
from .tables import CustomerTable
from .tables import TableView
from django_tables2.export.export import TableExport
def user_profile(request):
table= CustomerTable(Customer.objects.all())
RequestConfig(request,paginate={'per_page':15}).configure(table)
return render(request, 'home.html', {'table': table})
def TableView(request):
table = CustomerTable(Customer.objects.all())
RequestConfig(request).configure(table)
export_format = request.GET.get('_export', None)
if TableExport.is_valid_format(export_format):
exporter = TableExport(export_format, table)
return exporter.response('table.{}'.format(export_format))
return render(request, 'table.html', {
'table': table
})
my html template
{% extends 'base.html' %}
{% block content %}
{% load render_table from django_tables2 %}
{% load querystring from django_tables2 %}
<!doctype html>
<html>
<head>
<title>List of Customers</title>
</head>
<body>
{% querystring '_export'='csv' %}home
{% for format in table.export_formats %}
<a href="{% querystring '_export'=format %}">
download <code>.{{ format }}</code>
</a>
{% endfor %}
<p margin-bottom:500px;> </p>
<div style="width: 2500px; height: 600px; overflow-y: scroll;">
<div id ="users">
<input class="search" placeholder="Search" />
{% render_table table %}
{% endblock %}
</div>
</div>
</body>
urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^$', user_profile, name="user_profile"),
url(r'^$', TableView, name="TableView"),
]
tables.py
import django_tables2 as tables
from .models import Customer
from django_tables2.export.views import ExportMixin
from .models import Customer
class CustomerTable(tables.Table):
class Meta:
model = Customer
template = 'django_tables2/bootstrap.html'
class TableView(ExportMixin, tables.SingleTableView):
table_class = CustomerTable
model = Customer
template_name = 'django_tables2/bootstrap.html'
I have a feeling something is wrong with the way I have defined urls.py but i cannot figure out what is wrong
There is a note in the documentation on exporting saying:
This example assumes you define a list of possible export formats on your table instance in attribute export_formats.
So you need to add the desired export formats to a list on your table like this:
class CustomerTable(tables.Table):
export_formats = ['csv', 'xls']
class Meta:
model = Customer
template = 'django_tables2/bootstrap.html'
You an also define the list in a context variable for your template, if you prefer that. There is no 'right' in this.
So I also banged my head against the wall a little bit on this, and then in a moment of clarity it hit me, you need wrap the query string tag like this in the template file
download as csv

Form input-box not displaying

I'm trying to display a simple form input-text box with Django. I'm am deploying on Amazon AWS. The site works fine on a different server (pythonanywhere) but there is a major problem on AWS. Specifically, the input box is not being displayed. I'm using templates as follows:
home.html
{% extends 'lists/base.html' %}
{% block header_text %}Start a new To-Do list {% endblock %}
{% block form_action %}{% url 'new_list' %}{% endblock %}
base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X UA-Compatible" content="IE-edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>To-Do lists</title>
<link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/base.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3 jumbotron">
<div class="text-center">
<h1>{% block header_text %}{% endblock %}</h1>
<form method="POST" action="{% block form_action %}{% endblock %}">
{{ form.text }}
{% csrf_token %}
{% if form.errors %}
<div class = "form-group has-error">
<span class = "help-block">{{ form.text.errors }}</span>
</div>
{% endif %}
</form>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
{% block table %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>
models.py
from django.db import models
from django
.core.urlresolvers import reverse
class List(models.Model):
def get_absolute_url(self):
return reverse('view_list', args=[self.id])
# Create your models here.
class Item(models.Model):
text = models.TextField(default = '')
list = models.ForeignKey(List, default = None)
#list = models.ForeignKey(List , default=None)
forms.py
from django import forms
from lists.models import Item
EMPTY_ITEM_ERROR = "You can't have an empty list item"
class ItemForm(forms.models.ModelForm):
class Meta:
model = Item
fields = ('text',)
widgets ={
'text' : forms.fields.TextInput(attrs={
'placeholder': 'Enter a to-do item',
'class': 'form-control input-lg',
}),
}
error_messages = {
'text' : { 'required': EMPTY_ITEM_ERROR }
}
views.py
from django.shortcuts import redirect, render
from lists.models import Item, List
from django.core.exceptions import ValidationError
from lists.forms import ItemForm
from lists.models import Item, List
# Create your views here.
def home_page(request):
return render(request, 'lists/home.html', {'form': ItemForm()})
urls.py
from django.conf.urls import url
from lists import views
urlpatterns = [
url(r'^new$', views.new_list, name='new_list'),
url(r'^(\d+)/$', views.view_list, name='view_list'),
]
Currently the site displays the following:
However it should (and does on a different website) display this:
I've pushed/pulled the entire project to github and the code between each site is identical, yet I'm not seeing why the text input isn't displayed, unless the form needs to be initialized in Django somehow or a quirk to AWS?
When comparing the two sites, the one without the text-box does not generate the following:
<input class="form-control input-lg" id="id_text" name="text" placeholder="Enter a to-do item" type="text" />
Even though it should, per the base.html syntax.
Updated
The full views.py (per suggested comment) is:
from django.shortcuts import redirect, render
from lists.models import Item, List
from django.core.exceptions import ValidationError
from lists.forms import ItemForm
from lists.models import Item, List
# Create your views here.
def home_page(request):
return render(request, 'lists/home.html', {'form': ItemForm()})
def new_list(request):
form = ItemForm(data=request.POST)
if form.is_valid():
list_ = List.objects.create()
Item.objects.create(text=request.POST['text'], list=list_)
return redirect(list_)
else:
return render(request, 'lists/home.html', {"form": form})
def view_list(request, list_id):
list_ = List.objects.get(id=list_id)
form = ItemForm()
if request.method == 'POST':
form = ItemForm(data=request.POST)
if form.is_valid():
Item.objects.create(text=request.POST['text'], list=list_)
return redirect(list_)
return render(request, 'lists/list.html', {'list': list_, "form": form})
In my experience with Django, there are 2 things you often (always?) need to do to get static files to "refresh" after pushing them to a remote server:
Run ./manage.py collectstatic to make sure all your static files are in the right place.
While sshed into your server run the command sudo reboot now to restart your server (note that this will kick you out of your ssh session, and your server will be unreachable for a moment - usually just a few seconds in my case).
As for step 2 there might be a better way to do this, but in my experience, when I update static files the updated version is not served until I do this, and restarting nginx or the like is not sufficient for the changes to take effect. Note that this will mean that your site, if live, will not be reachable for a few seconds while the server is restarting (which is what makes me think there might be a better way to do it) but for me and my small user base this is not a big issue.
From reading some other posts about static files not updating, it seems like it could also be the case that your browser is caching the static files, and that restarting your browser/clearing the cache might do the trick as well, but I have not had a chance to try this yet.

Categories

Resources