Queried Results from Database Disappear on Pagination: Django - django

I am new to using the Django framework. I am creating a form to take in User input to query a database. I want to display the queried results on the same page, below the from fields. I am able to do the same. However, upon implementing Pagination, and clicking the 'next' link, or trying to sort the results using 'order_by', the queried results disappear from the webpage. How can this be resolved?
Below are my code files:\
views.py:
def get(self, request, *args, **kwargs):
paginated_objects = []
order_by = None
form = QueryForm(request.GET)
button_state = True
if form.is_valid():
max_traj_len = form.data["traj_len_user"]
print(form.data["submit"])
print(max_traj_len)
order_by = request.GET.get('order_by', 'traj_len') ##default order_by is set here
backtrack_flag = form.data["backtrack_user"]
print(backtrack_flag)
queried_objects = list(collection.find({'traj_len':{'$lte':int(max_traj_len)}}))
paginator = Paginator(queried_objects, 25)
page = request.GET.get('page')
paginated_objects = paginator.get_page(page)
button_state = request.GET.get('submit')
return render(request, self.template_name, {'form': form,'object_list': paginated_objects, 'order_by': order_by, 'button_state': button_state})
template.html:
{% extends 'base.html' %}
{% block content %}
<form action='' method='get'>
{% csrf_token %}
<table>{{ form.as_table }}</table>
<input type="submit" name="submit" value="Query">
</form>
{% if button_state == 'Query' %}
<table id="studata">
<thead>
<th>Traj ID</th>
<th>Traj Path</th>
<th>Traj Length</th>
<th>Interpolated_ID</th>
<th>Interpolated Path</th>
<th>Interpolated Path Length</th>
<th>Backtrack</th>
<th>Reached Goal</th>
</thead>
{% for obj in object_list %}<tr>
<script type="text/javascript">
var ele = {{ obj.traj_path }};
var last_ele = ele.pop()
//assuming 0 is the goal trajectory: change if another json is the goal state
if(last_ele == 0){
goal = "True"
}
else{
goal = "False"
}
</script>
<td><a href = '/hoc4/{{ obj.traj_id }}' >{{ obj.traj_id }}</a></td>
<td>{{ obj.traj_path }}</td>
<td>{{ obj.traj_len }}</td>
<td>{{ obj.interpolated_id }}</td>
<td>{{ obj.inter_path }}</td>
<td>{{ obj.inter_path_len }}</td>
<td>{{ obj.backtrack }}</td>
<td><script type="text/javascript">
document.write(goal)
</script>
</td>
</tr>
{% endfor %}
</table>
<div class="pagination">
<span class="step-links">
{% if object_list.has_previous %}
« first
previous
{% endif %}
<span class="current">
Page {{ object_list.number }} of {{ object_list.paginator.num_pages }}.
</span>
{% if object_list.has_next %}
next
last »
{% endif %}
</span>
</div>
{% endif %}
{% endblock %}
forms.py:
class QueryForm(forms.Form):
traj_len_user = forms.IntegerField(min_value=0, required=True)
backtrack_user = forms.BooleanField()

You're doing a lot of extra stuff that seems like you don't even need... You don't need a form for querying anything. You only need whatever's in request.GET and request.POST. You can access them by request.GET.get('name_attribute_of_input'), and so on.
Here's the relevant portion of how to use a Paginator class.
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def get_something(request):
object_list = MyModel.published.all()
tag = None
paginator = Paginator(object_list, 3) # 3 objects on each page
page = request.GET.get('page') # this is getting the 'page' quesry string argument in the url as a GET request, so ?page=whatever_url
try:
my_models = paginator.page(page) # by itself without paginator, object_list would get all my_models and put it on one page. But the paginator object here converts the X objects into pages.
# And those pages are reached by the page variable above that GET's it.
except PageNotAnInteger:
# If page is not an integer, deliver the 1st page
my_models = paginator.page(1)
except EmptyPage:
# If page is out of range deliver last page of results
my_models = paginator.page(paginator.num_pages)
return render(request, 'blog_app/list.html', {'page': page, 'my_models': my_models})
And your template would have something like this in it:
{% if page.has_previous %}
Previous
{% endif %}
<span class="current">
Page {{ page.number }} of {{ page.paginator.num_pages }}.
</span>
{% if page.has_next %}
Next
{% endif %}

Related

django keep populating Form data in table

I am pretty new to django I need to keep adding form data in to the html table in same page. I can populate one time but i need to keep adding each time.
refer below gif:
sample data
What I need is i need to add the data i have added second time to populate in the table in second row.
please help me on this
Form.py
from django import forms
class vm_provisioning_form(forms.Form):
name = forms.CharField()
email = forms.EmailField(
)
views.py
from django.shortcuts import render
from django.http import HttpResponse
from Forms import forms
def vm_provisioning(request):
form_vm_provisoning_info = forms.vm_provisioning_form()
hidden_values = []
if request.method == 'POST':
values = []
form_vm_provisoning_info = forms.vm_provisioning_form(request.POST)
if form_vm_provisoning_info.is_valid():
# DO SOMETHING CODE
print("VALIDATION SUCCESS!")
name = form_vm_provisoning_info.cleaned_data['name']
email = form_vm_provisoning_info.cleaned_data['email']
values.append([name, email])
return render(request, 'Forms_template/vm_provisioning/vm_provisioning_form.html', {'forms': form_vm_provisoning_info,'data': values })
return render(request, 'Forms_template/vm_provisioning/vm_provisioning_form.html', {'forms': form_vm_provisoning_info})
form_vm_provisoning_info.html
<!-- templates/vm_provisoning/form_vm_provisoning_info.html -->
<!DOCTYPE html>
{% extends 'Forms_template/base.html' %}
{% block title %}Login in registration{% endblock %}
{% block content %}
<h1> Vm provisoning form</h1>
<div class="container">
<h1>Please Fill details here!</h1>
<form method="POST">
{{ forms.as_p }}
{% csrf_token %}
<section>
<!-- hidden_data= forms.CharField(widget=forms.HiddenInput(), required=False) -->
{% if data %}
<table border="1">
<tr>
<th>Name</th>
<th>email</th>
</tr>
<!-- <p>{{ data }}</p> -->
{% for mapdata in data %}
<!-- <p>{{ mapdata }}</p> -->
<tr>
<td>{{ mapdata.0 }} </td>
<td>{{ mapdata.1 }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
</section>
<input type="submit" class='btn btn-primary' value="Submit">
</form>
</div>
{% endblock %}
Take a look at your views. This might be because you are assigning new values list everytime there is a POST request sent, instead try giving it above, also you must send the values list to the GET method also, so it always displays the data.
def vm_provisioning(request):
form_vm_provisoning_info = forms.vm_provisioning_form()
hidden_values = []
values = []
if request.method == 'POST':
form_vm_provisoning_info = forms.vm_provisioning_form(request.POST)
if form_vm_provisoning_info.is_valid():
# DO SOMETHING CODE
print("VALIDATION SUCCESS!")
name = form_vm_provisoning_info.cleaned_data['name']
email = form_vm_provisoning_info.cleaned_data['email']
values.append([name, email])
return render(request, 'Forms_template/vm_provisioning/vm_provisioning_form.html', {'forms': form_vm_provisoning_info,'data': values })
return render(request, 'Forms_template/vm_provisioning/vm_provisioning_form.html', {'forms': form_vm_provisoning_info,'data': values})

Flask Pagination with Sqlalchemy and JInja2 . Error : werkzeug.routing.BuildError werkzeug.routing.BuildError: ('users', {'page': 2}, None)

Hi I want to build a pagination with jinja2 -
Please help me
#app.route('/users')
def all_users():
users_list = User.query.paginate(1, per_page=2,error_out=False)
if users_list.has_next:
next_url = url_for('users', page=users_list.next_num)
if users_list.has_prev :
prev_url = url_for('users', page=users_list.prev_num)
return render_template("users.html", users=users_list.items,
next_url=next_url, prev_url=prev_url)
<------ users.html ----->
{% for user in users %}
<table>
<tr valign="top">
<td>{{ user.id }}</td>
<td>{{ user.user_fname }}</td>
</tr>
</table>
{% endfor %}
{% if prev_url %}
Newer posts
{% endif %}
{% if next_url %}
Older posts
{% endif %}
Every time I got the error like this -
werkzeug.routing.BuildError
werkzeug.routing.BuildError: ('users', {'page': 2}, None)
How can I solve this ?
Maybe you should fix it like this url_for(".users", page=users_list.next_num),
Be sure to define the function def users(page)

Django uploaded files not displaying in template page

I am trying to display the top 5 recently posted files but doesnt seem to show up.
When i get all the objects by using Model.objects.all(), it gives me all the objects from Db but when i am trying to get the top 5, it does not display.
Kindly help and suggest me. Thanks
my views.py is
def about_experiment(request, ex_link_name):
researcher = None
study = None
posts = None
exp = get_object_or_404(Experiment,link_name = ex_link_name)
high_scores = ScoreItem.objects.filter(experiment=exp,active=True)
context = {
'request': request,
'exp':exp,
'high_scores': high_scores,
'awards':AwardItem.objects.filter(experiment=exp,visible=True),
'posts':Help.objects.filter().order_by('-date')[0],
'documents':Help.objects.filter().order_by('-document')[:5]
}
if exp.about_file:
context['about_file'] = settings.EXPERIMENT_DIRS+exp.about_file.get_include_path()
if request.method == 'POST':
form = AboutHelp(request.POST, request.FILES)
if form.is_valid():
obj = form.save(commit = False)
obj.save()
return HttpResponseRedirect('/about/%s/' %ex_link_name)
#return redirect(reverse('lazer.views.about_experiment', kwargs={ 'ex_link_name':obj.link_name }))
else:
form = AboutHelp()
return render(request, 'about_experiment.html', context)
destination template page
<div class="tab-pane" id="irb">
<h4> List of file(s) uploaded:</h4>
<!--File upload-->
{% if documents %}
<ul>
<li> {{ documents.document }} </li>
</ul>
{% else %}
<p>No such documents available.</p>
{% endif %}
<!--File upload ends-->
documents is a queryset and you are picking top 5. You need to do this like this.
<div class="tab-pane" id="irb">
<h4> List of file(s) uploaded:</h4>
<!--File upload-->
{% for doc in documents %}
<ul>
<li> {{ doc.document }} </li>
</ul>
{% empty %}
<p>No such documents available.</p>
{% endfor %}
<!--File upload ends-->

Django - How to delete a object directly from a button in a table

(sorry for my bad english)
I need to delete an object, but directly from a list of the objects that y have in my template.
I have a work orders, that have spare parts but i don't know how to create the deleteview for the spare parts using only a buton in the detailview of the work order. The idea is that the user make click in the Delete button.
This is the model of the Spare Parts
class OrderSparePart(models.Model):
# Relations
workorder = models.ForeignKey(
WorkOrder,
verbose_name=_('order'),
)
# Attributes - Mandatory
spare_part = models.CharField(
max_length=80,
verbose_name=_('spare part'),
)
# Attributes - Optional
price = models.DecimalField(
max_digits=6,
decimal_places=2,
null=True,
blank=True,
verbose_name=_('price'),
)
# Object Manager
# Custom Properties
# Methods
def get_absolute_url(self):
return reverse('work_orders:detail', kwargs={'order_id': self.workorder.id})
# Meta and String
class Meta:
verbose_name = _("order spare part")
verbose_name_plural = _("order spare parts")
This is where is showed in the template
{% if spare_parts %}
<table class="table">
<thead>
<tr>
<th>{% trans "Spare Part" %}</th>
<th>{% trans "Price" %}</th>
<th>{% trans "Delete" %}</th>
</tr>
</thead>
<tbody>
{% for part in spare_parts %}
<tr>
<td><i class="fa fa-gear"></i> {{ part.spare_part }}</td>
{% if part.price %}
<td>$ {{ part.price }}</td>
{% else %}
<td></td>
{% endif %}
<td><i class="fa fa-trash"></i></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>NO HAY REPUESTOS ASENTADOS AÚN</p>
{% endif %}
The the idea is use the to delete the spare part.
how i have to make the deleteview and the link to this???
Thanks!
here in fa fa-thrash pass the id and the URL as I did it:-
{% if spare_parts %}
<table class="table">
<thead>
<tr>
<th>{% trans "Spare Part" %}</th>
<th>{% trans "Price" %}</th>
<th>{% trans "Delete" %}</th>
</tr>
</thead>
<tbody>
{% for part in spare_parts %}
<tr>
<td><i class="fa fa-gear"></i> {{ part.spare_part }}</td>
{% if part.price %}
<td>$ {{ part.price }}</td>
{% else %}
<td></td>
{% endif %}
<td></i></td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>NO HAY REPUESTOS ASENTADOS AÚN</p>
{% endif %}
ur url would be sonething like that:
url(r'^delete/(?P<part_id>[0-9]+)/$', view.function, name='delete_view'),
in ur view:
def function(request,part_id =None):
object = YourModel.objects.get(id=part_id)
object.delete()
return render(request,'ur template where you want to redirect')
In your html template inside for loop use the form tag inside <td> to create delete button as below (css class will work if you are using bootstrap3):
<form action="{% url 'delete_view' pk=part.pk %}" method="POST">
{% csrf_token %}
<input class="btn btn-default btn-danger" type="submit" value="Delete"/>
</form>
add urlpattern in urls.py
url(r'^delete-entry/(?P<pk>\d+)/$', views.DeleteView.as_view(), name='delete_view'),
delete view will be like below in views.py
class DeleteView(SuccessMessageMixin, DeleteView):
model = OrderSparePart
success_url = '/'
success_message = "deleted..."
def delete(self, request, *args, **kwargs):
self.object = self.get_object()
name = self.object.name
request.session['name'] = name # name will be change according to your need
message = request.session['name'] + ' deleted successfully'
messages.success(self.request, message)
return super(DeleteView, self).delete(request, *args, **kwargs)
Note: import necessary imports shown in links or you need not to worry if you are using IDE such as pyCharm it will prompt you which import to make.
My solutions works best for django 4.0.3 and is the combination of gahan and Abi waqas answers. Use this one if you are using django 3 or above
Add the following to views.py
def delete_object_function(request, id):
# OrderSparePart is the Model of which the object is present
ob = OrderSparePart.objects.get(id=id)
ob.delete()
return redirect('page-delete.html') # for best results, redirect to the same page from where delete function is called
Add the following to urls.py
path('page-delete/<int:id>', views.delete_object_function, name='delete_object'),
Add the following code to the django template from where the delete function is to be called.
Let's say page-delete.html
<form action="{% url 'delete_object' id=part.id %}" method="post">
{% csrf_token %}
<button class="btn btn-danger" type="submit" ><i class="fa fa-trash"></i></button>
</form>
This works as I've used this solution in my own code.

Django formset only adding one form

OK, so this is my first time using formsets. I am trying to create a table that I can dynamically add rows to and fill out each row, then submit and have Django put them all in the database. Every time I submit it only adds the first form.
File views.py:
#main_context_wrapper
def bacteriaForm2(request,context):
if not request.user.is_authenticated():
#If user isn't authenticated, then just redirect to login
return HttpResponseRedirect('/login/')
BacteriaFormSet = formset_factory(BacteriaForm)
if request.POST:
bacteriaformset = BacteriaFormSet(request.POST, request.FILES)
if bacteriaformset.is_valid():
context["error"] = ""
for form in bacteriaformset:
form.save()
return HttpResponseRedirect('/')
else:
context["error"] = "validation"
context["bacteriaformset"] = BacteriaFormSet
context.update(csrf(request))
return render_to_response('bacteriaForm.html', context)
else:
#The request was a GET, add the form to the context
context["bacteriaformset"] = BacteriaFormSet()
#Add all siteInfo objects to allow for dynamic site info drop down menus
siteInfo = SiteInfo.objects.all()
context["siteInfo"] = siteInfo
return render(request, "bacteriaForm.html", context)
Template:
{% extends "inherited/main.html" %}
{% block content %}
<h1> Bacteria Entry Form </h1>
<form action='/bacteriaForm/' method="post">{% csrf_token %}
{{bacteriaformset.management_form}}
{% if error == "validation" %}
<div class="alert alert-danger">
<p>
<strong>Error: </strong>Form not completed properly.
</p>
</div>
{% endif %}
<table id="id_forms_table">
<tr>
{% for field in bacteriaformset.forms.0 %}
{% if not field.is_hidden %}
<th>{{ field.label }}</th>
{% endif %}
{% endfor %}
</tr>
{% for f in bacteriaformset.management_form %}
{{ f }}
{% endfor %}
{% for f in bacteriaformset.forms %}
<tr id="{{ f.prefix }}-row" class="dynamic-form">
{% for field in f %}
{% if not field.is_hidden %}
<td>
{{ field.errors }}
{{ field }}
</td>
{% else %}
<td valign="bottom">{{ field }}</
{% endif %}
{% endfor %}
<td{% if forloop.first %} class="hidden"{% endif %}>
<a id="remove-{{ form.prefix }}-row" href="javascript:void(0)" class="delete-row">delete</a>
</td>
</tr>
{% endfor %}
<tr>
<td colspan="4">add property</td>
</tr>
</table>
<div>
<input type="submit" value="submit" />
</div>
</form>
<script>
$(function () {
$('.add-row').click(function() {
return addForm(this, 'form');
});
$('.delete-row').click(function() {
return deleteForm(this, 'form');
});
});
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function addForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
var row = $('.dynamic-form:first').clone(true).get(0);
$(row).removeAttr('id').insertAfter($('.dynamic- form:last')).children('.hidden').removeClass('hidden');
$(row).children().not(':last').children().each(function() {
updateElementIndex(this, prefix, formCount);
$(this).val('');
});
$(row).find('.delete-row').click(function() {
deleteForm(this, prefix);
});
$('#id_' + prefix + '-TOTAL_FORMS').val(formCount + 1);
return false;
}
function deleteForm(btn, prefix) {
$(btn).parents('.dynamic-form').remove();
var forms = $('.dynamic-form');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).children().not(':last').children().each(function() {
updateElementIndex(this, prefix, i);
});
}
return false;
}
$("#id_date").datepicker();
</script>
{% endblock %}
File Models.py
class BacteriaEntry(models.Model):
"""
A bacteria entry contains information about a test set's
bacteria levels at a specific time. BacteriaEntry utilizes the
Djano model.
"""
siteNumber = models.IntegerField()
date = models.DateField()
sampleNumber = models.IntegerField(primary_key=True)
ecoliRawCount = models.IntegerField(null=True)
ecoli = models.DecimalField(decimal_places=10, max_digits=20, null=True)
ecoliException = models.IntegerField(null=True)
coliformRawCount = models.IntegerField(null=True)
coliform = models.DecimalField(decimal_places=10, max_digits=20, null=True)
coliformException = models.IntegerField(null=True)
comments = models.CharField(max_length=2000, null=True)
"""Returns the sample number of the Bacteria Entry"""
def __unicode__(self):
return smart_unicode(self.sampleNumber)
Here is some post data
<QueryDict: {u'form-0-date': [u'02/24/2014'], u'form-0-comments': [u'65'], u'form- MAX_NUM_FORMS': [u'1000', u'1000'], u'form-0-coliformRawCount': [u'5'],
u'form-0-coliform': [u'65'], u'form-0-ecoliException': [u'56'], u'form-TOTAL_FORMS': [u'1', u'1'], u'form-0-sampleNumber': [u'1554'], u'form-0-ecoliRawC
ount': [u'35'], u'form-0-coliformException': [u'56'], u'form-INITIAL_FORMS': [u'0', u'0'], u'csrfmiddlewaretoken': [u'VSnaJCW6R9z8iEKib46cHuBJ6AKTPPUT'],
u'form-0-ecoli': [u'51'], u'form-0-siteNumber': [u'100']}>
I'm not exactly sure where my problem is. I have spent a lot of time trying to figure this out. I am not sure what is wrong.
You're not printing formset.non_form_errors, or form.non_field_errors in any of the child forms, in your template - there's probably something in one of those that is causing validation to fail.
I should also point out that there is no need to instantiate the form separately from the formset. It makes no sense to create a separate BacteriaForm instance and pass it to the template, then validate it on post: that's what the formset is for, after all.
I'm a bit confused with this, not sure why you need both a Form and a FormSet, especially because the FormSet contains the same Forms as is the separate Form...
But if that is the case, then you should use prefix on the Form and/or on the FromSet:
bacteriaForm = BacteriaForm(request.POST, prefix='the_one_bacteria')
bacteriaformset = BacteriaFormSet(request.POST, request.FILES, prefix='bacterias')
and also in the else: part of the View.
Pardon my plural.