Python: Get multiple id's from checkbox - python

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

Related

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.

Building a dynamic table with jinja2, html and flask

<table style="width:100%", border="1">
{% for item in items %}
<tr>
<td>{{Description[item]}}</td>
<td>{{Location[item]}}</td>
<td>{{Status[item]}}</td>
</tr>
{% endfor %}
</table>
I am trying to create a table using this for loop, the variables are being passed through in the flask framework, 'items' will always be the same length as the three lists (Description, location and status).
I am aware of the question below:
How to build up a HTML table with a simple for loop in Jinja2?
but I can not see how my code here differs to the working answer to this question, is it because I am using a list instead of a dictionary ?
This is the flask framework, where the lists
are created an passed through using render template:
def index():
description = []
location = []
status = []
imix80m = ''
imix = ''
with open('behavepretty.json') as a:
data = json.load(a)
for n in range(0,len(data)):
i = 0
for i in range(0, len(data[n]['elements'])):
x = data[n]['elements'][i]['name']
description.append(x)
y = data[n]['elements'][i]['location']
location.append(y)
z = data[n]['elements'][i]['status']
status.append(z)
n = 0
for n in range(0,len(data)):
if n == 0:
imix80m = data[n]['status']
elif n == 1:
imix = data[n]['status']
a.close()
return render_template('trial.html', Description = description, Location= location, Status = status, result1 = imix80m, result2 = imix, jfile = data, items = description)
You just need a loop counter:
<table style="width:100%", border="1">
{% for item in Description %}
<tr>
<td>{{Description[loop.index0 ]}}</td>
<td>{{Location[loop.index0]}}</td>
<td>{{Status[loop.index0]}}</td>
</tr>
{% endfor %}
</table>
Or, you could pack the 3 into a list of lists:
my_list = [[Description0, Location0, Status0], [Description1, Location1, Status1], ...]
Then:
{% for item in my_list %}
<tr>
<td>{{ item[0] }}</td>
<td>{{ item[1] }}</td>
<td>{{ item[2] }}</td>
</tr>
{% endfor %}
Or, more robustly, a list of dictionaries:
my_list = [
{
"description" : xxx,
"location" : yyy,
"status" : zzz
},
{
"description" : www,
"location" : eee,
"status" : rrr
},
...
]
Then:
{% for item in my_list %}
<tr>
<td>{{ item.description }}</td>
<td>{{ item.location }}</td>
<td>{{ item.status }}</td>
</tr>
{% endfor %}

Flask WTForms Dynamic Editable Table Fields with Field Names

How can I get the Field Names to return as text/string?
Highlighted "Field Names" I want returned as text, not fields
I am dynamically creating a list of fields and then appending values. But I can't seem to figure out a way to return the field names as plain text. The below code appends them to a field (fieldname)-- which is the only way I have been able to return them.
class ContractFields(FlaskForm):
fieldname = StringField()
fieldvalue = StringField()
class ContractForm(FlaskForm):
title = StringField('title')
contractfieldlist = FieldList(FormField(ContractFields))
#app.route('/tester.html', methods=['GET','POST'])
def contractfields():
form = ContractForm()
for f in object:
document_form = ContractFields()
document_form.fieldname = f.name #need this list object to return as table text, not a field
document_form.fieldvalue = f.value
form.contractfieldlist.append_entry(document_form)
return render_template('tester.html', form = form)
And from the template:
<div>
<form action="" method="post" name="form">
{{ form.hidden_tag() }}
<div>
<table>
<tr>
<th> ListNumber </th>
<th> Field Name </th>
<th> Field Value </th>
</tr>
{% for items in form.contractfieldlist %}
<tr>
<td>{{ items.label }}</td>
<td>{{ items.fieldname }}</td>
<td>{{ items.fieldvalue }}</td>
</tr>
{% endfor %}
</table>
</div>
<p><input type="submit" name="edit" value="Send"></p>
</form>
</div>
My experience with Python has largely been limited ETL and data transformation so I don't understand why this was so complicated. But after way too many hours I finally found the following solution worked for me.
Specifically modifying the associated excerpt from the above post to be the following:
class ContractFields(FlaskForm):
fieldname = HiddenField()
fieldvalue = StringField()
def __init__(self, *args, **kwargs):
super(ContractFields, self).__init__(*args, **kwargs)
if 'obj' in kwargs and kwargs['obj'] is not None:
self.fieldvalue.label.text = kwargs['obj'].fieldname
And the template html to:
<td>{{ items.label }}</td>
<td>{{ items.fieldvalue.label }}</td>
<td>{{ items.fieldvalue }}</td>

Django passing dictionary of tuples to template

If I made a set of code like this...
object_data = {}
object = Object.objects.all()
for o in object:
ratings = ObjectRating.objects.filter(recipe=r)
counter = 0
ratings_sum = 0
for s in ratings:
counter += 1
ratings_sum += s.rating
rating_average = ratings_sum / counter
object_data[`o.id`] = (o, rating_average,)
data = {
'search_by' : search_by,
'object' : object_data
}
If I pass the data dictionary to the page (render_to_response(page, data, context_instance=RequestContext(request))), how do I get the data from both parts of the tuple in the template.
This is how I thought I had to do it...
{% for o in object %}
<tr><td>{{ o.0.name }}</td><td>{{ o.0.description }}</td><td>{{ o.0.other_col }}</td><td>{{ o.0.another_col }}</td><td>{{ o.1 }}</td></tr>
{% endfor %}
This is driving me insane and any insight will be helpful. This is Django 1.6 (I know I need to move on, so do not mention that in your answer).
Why not just add rating_average as an attribute to your object?
for o in object:
... # calculate rating average for this object
o.rating_average = ratings_sum / counter
data = {
'search_by' : search_by,
'object' : object
}
{% for o in object %}
<tr><td>{{ o.name }}</td>
<td>{{ o.description }}</td>
<td>{{ o.other_col }}</td>
<td>{{ o.another_col }}</td>
<td>{{ o.rating_average }}</td>
</tr>
{% endfor %}
Like this example:
class HomeView(generic.TemplateView):
template_name = '_layouts/index.html'
def get_context_data(self, **kwargs):
context = super(HomeView, self).get_context_data(**kwargs)
mydict = {'wat': 'coo'}
context['mydict'] = mydict
return context
Template:
{% for key, value in mydict.items %}
{{ key }} : {{ value }}
{% endfor %}

Django Forms: Get selected item from ModelChoiceField?

I'd like to access the selected item from a ModelChoiceField, similar to this:
forms.py
class ManageFeedsForms(forms.Form):
active_feed = forms.ModelChoiceField(queryset=Feed.objects.all(),
empty_label=None,
widget=forms.Select(attrs={'onchange': 'this.form.submit();'}),
)
def __init__(self, *args, **kwargs):
super(ManageFeedsForms, self).__init__(*args, **kwargs)
self.fields['active_feed'].label = ''
Template.html
{% for entry in feed_form.active_feed.selected_item.entry_list %}
<tr>
<td>{{ entry.title }}</td>
<td>{{ entry.date }}</td>
</tr>
{% endfor %}
views.py (very basic, just for testing)
def overview(request):
if request.GET:
form = ManageFeedsForms(request.GET)
if form.is_valid():
pass
else:
pass
else:
# Empty ManageFeedsForms
form = ManageFeedsForms()
return render_to_response('feed_management/home.html',
{'header_title': 'Feeds',
'feed_form' : form,
},
context_instance=RequestContext(request))
I'm looking for something like '.selected_item', so I can access the model's attributes.
Thanks for any help!
You should modify your view like so:
def overview(request):
selection = None
if request.GET:
form = ManageFeedsForms(request.GET)
if form.is_valid():
selection = form.cleaned_data['active_feed']
else:
# Empty ManageFeedsForms
form = ManageFeedsForms()
return render_to_response('feed_management/home.html',
{'header_title': 'Feeds',
'feed_form' : form,
'selection' : selection,
},
context_instance=RequestContext(request))
And your template:
{% if selection %}
<tr>
<td>{{ selection.title }}</td>
<td>{{ selection.date }}</td>
</tr>
{% endif %}

Categories

Resources