Django views.py Exception Value: Could not parse the remainder: - python

I get an Exception Value error:
Could not parse the remainder: '(column)' from 'item.get(column)'
views.py:
def home(request):
position = DjangoEmail.objects.get(Email=request.user).Position
year_filter = Q(Year=now.year) | Q(Year=now.year-1) | Q(Year=now.year+1)
if position == 7:
data = Employee.objects.filter(year_filter, Mlkk=request.user).order_by('Year','OblastTM').values('Year', 'OblastTM', 'Category', 'ProductGroup','NameChaine').annotate(Januaru=Sum('January'))
elif position == 6:
data = Employee.objects.filter(year_filter, Rmkk=request.user).order_by('Year','OblastTM').values('Year', 'OblastTM', 'Category', 'ProductGroup','NameChaine').annotate(Januaru=Sum('January'))
elif position == 5:
data = Employee.objects.filter(year_filter, Dmkk=request.user).order_by('Year','OblastTM').values('Year', 'OblastTM', 'Category', 'ProductGroup','NameChaine').annotate(Januaru=Sum('January'))
else:
data = Employee.objects.filter(year_filter).order_by('Year','OblastTM').values('Year', 'OblastTM', 'Category', 'ProductGroup','NameChaine').annotate(Januaru=Sum('January'))
columns = ['Year', 'OblastTM', 'Category', 'ProductGroupe', 'NameChaine','January']
removed_columns = request.GET.getlist('remove')
columns = [column for column in columns if column not in removed_columns]
return render(request, "home.html", {'data': data, 'columns': columns})
home.html:
<table>
<thead>
<tr>
{% for column in columns %}
<th>{{ column|title }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for item in data %}
<tr>
{% for column in columns %}
<td>{{ item.get(column)}}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
error:
Exception Value:Could not parse the remainder: '(column)' from 'item.get(column)'
Error in the line :
<td>{{ item.get(column)}}</td>
I tried to replace it with {{ item\[column\] }} - it didn't help.

You can not subscript or call methods in Django templates, hence {{ item.get(column) }} is not possible. This is often not a good idea anyway: you should pass the data in an accessible format to the template.
You thus prepare this as:
from operator import itemgetter
def home(request):
position = get_object_or_404(DjangoEmail, Email=request.user).Position
year_filter = Q(Year__range=(now.year - 1, now.year + 1))
columns = [
'Year',
'OblastTM',
'Category',
'ProductGroupe',
'NameChaine',
'Januaru',
]
removed_columns = set(request.GET.getlist('remove'))
columns = [column for column in columns if column not in removed_columns]
queryset = Employee.objects.filter(year_filter)
if position == 7:
queryset = queryset.filter(Mlkk=request.user)
elif position == 6:
queryset = queryset.filter(request.user)
elif position == 5:
queryset = queryset.filter(Dmkk=request.user)
queryset = (
queryset.order_by('Year', 'OblastTM')
.values('Year', 'OblastTM', 'Category', 'ProductGroupe', 'NameChaine')
.annotate(Januaru=Sum('January'))
)
if columns:
getter = itemgetter(*columns)
if len(columns) == 1:
data = [(getter(data),) for data in queryset]
else:
data = [getter(data) for data in queryset]
else:
data = ((),) * queryset.count()
return render(request, 'home.html', {'data': data, 'columns': columns})
then we can render this with:
<thead>
<tr>
{% for column in columns %}
<th>{{ column|title }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for row in data %}
<tr>
{% for cell in row %}
<td>{{ cell }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>

Related

Python: Get multiple id's from checkbox

I wanted to get multiple id's from a list using checkbox. I got an error
Field 'id' expected a number but got [].
Below is my code.
sample.html
<button href="/sample/save">Save</button>
{% for obj in queryset %}
<tr>
<td><input type="checkbox" name="sid" value="{{obj.id}}"></td>
<td>{{ obj.sample_name }}</td>
<td>{{ obj.sample_type}}</td>
<td>{{ obj.number}}</td>
</tr>
{% endfor %}
views.py
def sample(request):
if request.method == 'GET':
queryset = SampleList.objects.all()
return render(request, 'lab_management/sample.html', {'queryset': queryset})
def save_doc(request):
sid = request.POST.getlist('sid')
sample = SampleList.objects.filter(id=sid)[0:10]
template = DocxTemplate("doc.docx")
context = {
'headers' : ['Name', 'Type', 'Number'],
'doc': [],
}
for samp in sample:
list = [samp.name, samp.type, samp.number]
context['doc'].append(list)
template.render(context)
template.save('new_doc.docx')
the field id should be int you passed a list, that's why you got error:
Field 'id' expected a number but got [].
Here you can use the in Filed lookup
Try this
sample = SampleList.objects.filter(id__in=sid)[0:10]
this will show all the SampleList items with the id's in sid
Update
Change your context to
context = {
'headers' : ['Name', 'Type', 'Number'],
'doc': sample,
}
then remove this for loop
# for samp in sample:
# list = [samp.name, samp.type, samp.number]
# context['doc'].append(list)
and in your template
{% for obj in doc %}
<tr>
<td><input type="checkbox" name="sid" value="{{obj.id}}"></td>
<td>{{ obj.name }}</td>
<td>{{ obj.type}}</td>
<td>{{ obj.number}}</td>
</tr>
{% endfor %}
NB: assuming name, type and number are the filed names of SampleList model

How to create a pagination for a dataframe?

I want to create a pagination system for my dataframe. I always create pagination with my queries but It doesn't work in dataframe. I cannot display on my template.
This is my views.py
def get_context_data(self, **kwargs):
...
df = pd.DataFrame(list(Case.objects.all().values(...)))
query = df.assign(cnt=1).groupby([...)['cnt'].sum().reset_index()
paginator = Paginator(query, 10)
page_number = self.request.GET.get('page')
if page_number == None:
page_number = 1
page_obj = paginator.page(int(page_number))
print(page_obj) ----> <Page 1 of 33>
context['query'] = query
return context
And this is my template
<table class="table table-bordered" >
<tbody>
{% for index, row in query.iterrows %}
<tr>
{% for cell in row %}
<td>
{{cell}}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
Table shows nothing. How can I solve that?

Django-filter: count data

Does anybody knows how can I use count based on selected value using django_filters
Error
'UserFilter' object has no attribute 'count'
My Reference link
views.py
def search(request):
user_list = Person.objects.all()
user_filter = UserFilter(request.GET, queryset=user_list)
count = user_filter.count() #this will return an error
print(count)
return render(request, 'user_list.html', {'filter': user_filter})
filters.py
from django.contrib.auth.models import User
from .models import Person
import django_filters
class UserFilter(django_filters.FilterSet):
class Meta:
model = Person
fields = ['category', 'firstname', 'lastname' ]
user_list.html
{% extends 'base.html' %}
{% block content %}
<form method="get">
{{filter.form.as_p}}
<button type="submit" >Search</button>
</form>
<table class="table table-bordered">
<thead>
<tr>
<th>Firstname</th>
<th> Lastname</th>
<th>Caegory</th>
</tr>
</thead>
<tbody>
{% for user in filter.qs %}
<tr>
<td>{{ user.firstname }}</td>
<td>{{ user.lastname }}</td>
<td>{{ user.category }}</td>
</tr>
{% empty %}
<tr>
<td colspan="5">No data</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
I want to count all the list base from data I filtered
You'll want the count of the resulting queryset, which you can get from the filter's qs property (as you do in your template!).
Change
count = user_filter.count()
to
count = user_filter.qs.count()
You can work with the .qs attribute:
def search(request):
user_list = Person.objects.all()
user_filter = UserFilter(request.GET, queryset=user_list)
count = user_filter.qs.count()
return render(request, 'user_list.html', {'filter': user_filter})
.qs [GitHub] is a property that generates a QuerySet by filtering the original queryset by values in the fields of the FilterSet.

Cant Turn Tuple Into String

I am struggling to display two columns (resultlist) in seperate columns. Right now when i return result list its showing in a tuple. When i try to index the for loop(to remove the tuple) with i[0] in the HTML file but i get the first character which is the "("
current output:
column1
('123456', '150.92')
('49815', '70.43')
('19971', '39.35')
If i try to index the for loop in html, current output:
column1
(
(
(
expected output:
Column1 Column2
123456 150.92
49815 70.43
19971 39.35
Current python file:
def subtractboth(alloclist, statementlist):
resultlist = []
for i, j in zip(statementlist, alloclist):
if i[0] == j[0]:
results = float(j[1]) - float(i[1])
if results >= 0:
results = i[0], "{:.2f}".format(results)
print(" ".join(results))
resultlist.append(str(results))
return resultlist
#app.route('/results', methods=['GET', 'POST'])
def main():
connect()
masteracct = request.args.get('masteracct')
cashdt = request.args.get('cashdt')
billdt = request.args.get('billdt')
allocation(connect(), cashdt, masteracct)
statement(connect(), billdt, masteracct)
a = subtractboth(statement(connect(), billdt, masteracct), allocation(connect(), cashdt,
masteracct))
html = render_template('test_results.html', a=a)
return html
HTML:
<table>
<th>Column 1</th>
<th> Column 2</th>
{% for i in a %}
<tr>
<td>{{i}}</td>
<td>{{i}}</td>
</tr>
{% endfor %}
</table>
The Jinja2 template for displaying a table with 2 columns should look like this:
<table>
<tr>
<th>column1</th>
<th>column2</th>
</tr>
{% for v1, v2 in a %}
<tr>
<td>{{ v1 }}</td>
<td>{{ v2 }}</td>
</tr>
{% endfor %}
</table>
The variable a should be a sequence of pairs.

Django-tables2 render merged tables

I use django-tables2 and have following table, which is populated by generated dictionary:
class SimpleStatTable(tables.Table):
Metric = tables.Column(accessor='metric')
Qty = tables.Column(accessor='qty')
Min = tables.Column(accessor='min')
Avg = tables.Column(accessor='avg')
Max = tables.Column(accessor='max')
def __init__(self, data, label=None, **kwargs):
self.label = label
super(SimpleStatTable, self).__init__(data, **kwargs)
class Meta:
order_by = ('Metric',)
empty_text = 'No data presented'
I want to render merged table of a few SimpleStatTable tables. Is it possible with django-tables2? I like django-tables2 features, such as sorting
I have a small example of desired tables.
I suppose i need to generate class for merged table dynamically like here, but how can i add additional merged column?
I have a solution, but it's not elegant.
I merge two dictionaries and build table for merged dictionary. After that i just add merged columns to the table. They are in same order as in merged dictionary. Also I've changed template for the table for handling merged columns.
Here is the code:
from collections import defaultdict
import django_tables2 as tables
def merge_table_dicts(labels, tables, key_column):
merged_tables = []
for table, label in zip(tables, labels):
new_table = []
for row in table:
new_row = {}
for key, value in row.iteritems():
if key == key_column:
new_row[key] = value
else:
new_row[old_key + '_' + label] = value
new_table.append(new_row)
merged_tables.append(new_table)
d = defaultdict(dict)
for l in merged_tables:
for elem in l:
d[elem[key_column]].update(elem)
merged_table_dicts = d.values()
return merged_table_dicts
def get_merged_table(labels, tables_dicts, key_column_name, merged_columns_order):
attrs = {}
# General options
class Meta:
order_by = (key_column_name,)
template = '_merged_table.html'
empty_text = 'No data presented'
attrs['Meta'] = Meta
attrs[key_column_name] = tables.Column()
for column in merged_columns_order:
for label in labels:
attrs[get_merged_key(column, label)] = tables.Column(verbose_name=label)
merged_table = type('MergedTable', (tables.Table,), attrs)
merged_columns = []
for merged_column_name in merged_columns_order:
column = tables.Column(verbose_name=merged_column_name,
attrs={"th": {"rowspan": len(labels)}})
merged_columns.append(column)
merged_table.merged_columns = merged_columns
# Merge data for table
data = merge_table_dicts(labels, tables_dicts, key_column_name)
return merged_table(data)
And it's a changed part of a template:
<thead>
<tr>
{% with column=table.columns|first %}
{% if column.orderable %}
<th rowspan="2" {{ column.attrs.th.as_html }}>{{ column.header }}</th>
{% else %}
<th rowspan="2" {{ column.attrs.th.as_html }}>{{ column.header }}</th>
{% endif %}
{% endwith %}
{% for column in table.merged_columns %}
<th colspan="{{ column.attrs.th.rowspan }}">{{ column.header }}</th>
{% endfor %}
</tr>
<tr>
{% for column in table.columns %}
{% if not forloop.first %}
{% if column.orderable %}
<td {{ column.attrs.th.as_html }}>{{ column.header }}</td>
{% else %}
<td {{ column.attrs.th.as_html }}>{{ column.header }}</td>
{% endif %}
{% endif %}
{% endfor %}
</tr>
</thead>

Categories

Resources