I'm building a ecommerce site with django.
I'm creating the page where the orders are processed.
I want to make it so that when an item is "delivered" that order will go to the bottom of the list.
views.py
def orders(request, hour):
#changes status of order from submitted to shipped
if request.method == 'POST':
SUBMITTED = 1
PROCESSED = 2
SHIPPED = 3
CANCELLED = 4
order_id = request.POST['order_id']
this_order = Order.objects.get(pk=order_id)
if this_order.status == SUBMITTED or this_order.status == PROCESSED:
this_order.status = SHIPPED
elif this_order.status == SHIPPED:
this_order.status = SUBMITTED
this_order.save()
return HttpResponseRedirect('/orders/' + hour)
#Get all orders from the past 24 hours
tz=pytz.timezone('America/Los_Angeles')
now_nonaware = datetime.datetime.now()
now = timezone.make_aware(now_nonaware,tz)
orders = Order.objects.filter(date__range=[now - datetime.timedelta(hours=20), now]).filter(time=hour)
#get all orders from every college drop
revelle_orders = orders.filter(location = "revelle")
muir_orders = orders.filter(location = "muir")
marshall_orders = orders.filter(location = "marshall")
erc_orders = orders.filter(location = "erc")
warren_orders = orders.filter(location = "warren")
sixth_orders = orders.filter(location = "sixth")
orderlocations = {"revelle": revelle_orders, "muir" : muir_orders, "marshall" : marshall_orders,
"erc": erc_orders, "warren": warren_orders, "sixth": sixth_orders}
orders_dict = {"orderlocations" : orderlocations, "hour": hour}
return render_to_response('orders.html', orders_dict, context_instance=RequestContext(request))
HTML:
Order page for {{hour}}
</br>
</br>
{% for location, orders in orderlocations.items %}
{% if orders %}
{{ location|capfirst }}
<table>
<tr>
<td>#</td>
<td>Name</td>
<td>Email</td>
<td>Order</td>
<td>Delivered</td>
<td>Phone</td>
</tr>
{% for ord in orders %}
{% for food in ord.orderitem_set.all %}
<tr>
{% if forloop.counter == 1 %}
<td>{{forloop.parentloop.counter}}</td>
<td>{{ord.full_name}}</td>
<td>{{ord.email}}</td>
{% else %}
<td colspan="3"></td>
{% endif %}
<td>{{food.name}} (x{{food.quantity}})</td>
{% if forloop.counter == 1 %}
<td>
<form action="" method="POST">
{% csrf_token %}
<input type="hidden" name="order_id" value="{{ ord.pk }}"/>
<input type="hidden" name="action=" value="toggledelivery"/>
<button type="submit">{% ifnotequal 3 ord.status %} Not {% endifnotequal %}Delivered</button>
</form>
</td>
<td>{{ord.phone}}</td>
{% endif %}
</tr>
{% endfor %}
{% endfor %}
</table>
</br>
</br>
{% endif %}
{% endfor %}
This sounds like a job for model ordering meta options on a class.
For example in your model class add a sub-class called Meta:
class MyModel(models.Model):
# model fields here...
class Meta:
ordering = ['status']
You can add a - in front of status to sort in descending order. You can also chain together multiple fields for ordering:
class Meta:
ordering = ['status', '-order_date']
hmm since there's this part
<button type="submit">{% ifnotequal 3 ord.status %} Not {% endifnotequal %}Delivered</button>
maybe something like this in your orders view?
orders = Order.objects.filter(date__range=[now - datetime.timedelta(hours=20), now]).filter(time=hour).extra({"is_completed_order": "status == 3"}).order_by('is_completed_order')
e.g. compute an extra is_completed_order boolean field and order on that
Related
How can I hide an entire row if one or more specific fields are empty? For example, I have a django query set up so that I can get a total profit from items in the inventory manager. The way that I have that written is like:
html
{% extends 'portal/base.html' %}
{% block title %}Inventory{% endblock %}
{% block content %}
<br>
<div class="row">
<div class="col">
<form class="d-flex" role="search" action="/search" method="get">
<input class="form-control me-2" type="text" name="q" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success">Search</button>
</form>
</div>
<div class="col">
<a class="btn btn-primary me-md-2" href="/newitem" type="button">Input New Purchase</a>
</div>
</div>
</div>
<table class="table table-striped">
<thead>
<tr>
<th>Breakdown</th>
<th>Product ID</th>
<th>Product</th>
<th>Total Profit</th>
</tr>
</thead>
{% for inventory in inventory %}
<tr>
<td><a class='btn btn-success btn-sm' href=''>View Breakdown</a>
<td>{{inventory.id}}</td>
<td>{{inventory.product}}</td>
<td>{{ inventory.Calculate_profit }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
views.py
#login_required(login_url="/login")
def profitsperitem(request):
inventory = Inventory.objects.all().order_by('id')
return render(request, 'portal/profitsperitem.html', {"inventory": inventory})
models.py
#property
def Calculate_profit(self):
soldfor = Inventory.objects.filter(soldprice=self.soldprice).aggregate(Sum('soldprice'))['soldprice__sum'] or 0.00
paidfor = Inventory.objects.filter(paid=self.paid).aggregate(Sum('paid'))['paid__sum'] or 0.00
shipfor = Inventory.objects.filter(shipcost=self.shipcost).aggregate(Sum('shipcost'))['shipcost__sum'] or 0.00
totalprofit = soldfor - paidfor - shipfor
return totalprofit
As long as the model fields soldprice , paid , and shipcost are all filled out on every row in the database, I can get the results no problem. I get an error if soldprice or shipcost are null or none, so when there is nothing added to database. If one row does not have soldprice or shipcost set, none of the results can be viewed as this error pops up: "TypeError at /profitsperitem
unsupported operand type(s) for -: 'float' and 'decimal.Decimal'"
My question is how can I hide the entire row if either or both soldprice and/or shipcost are empty?
Tho filter all rows with any of the two fields beeing null/None use a query like this
from django.db.models import Q
#login_required(login_url="/login")
def profitsperitem(request):
inventory = Inventory.objects.filter(
Q(soldprice__isnull = False) | Q(shipcost__isnull = False)
).order_by('id')
return render(request, 'portal/profitsperitem.html', {"inventory": inventory})
I was able to update the view like this
#login_required(login_url="/login")
def profitsperitem(request):
inventory = Inventory.objects.filter(soldprice__isnull = False, shipcost__isnull = False).order_by('id')
return render(request, 'portal/profitsperitem.html', {"inventory": inventory})
{% for inventory in inventory %}
{% if inventory.Calculate_profit %}
<tr>
<td><a class='btn btn-success btn-sm' href=''>View Breakdown</a>
<td>{{inventory.id}}</td>
<td>{{inventory.product}}</td>
<td>{{ inventory.Calculate_profit }}</td>
</tr>
{% endif %}
{% endfor %}
you can print row only if you have calculate price.
if(soldfor is not None and paidfor is not None and shipfor is not None )
totalprofit = soldfor - paidfor - shipfor
else totalprofit =None
Also You can check if Calculate profit has some value
I am new to Python and Django and I am trying to count the number items(documents) in my SQLite database base on the status of the document, (canceled or not canceled). I have tried multiple ways to do this but, I cannot find one that works correctly for me. I have tried forloop.counter, .count(), and a few other ways that i found online. All I want to do is go through the database and have it tell me how many canceled procedures I have in the database. I am trying to display the results on a html page. Thanks.
models.py
class posts(models.Model):
OPMnumber = models.CharField(max_length = 30)
title = models.TextField()
contacts = models.CharField(max_length = 50)
dateLastReviewed = models.DateTimeField()
reviewDue = models.DateTimeField()
status = models.CharField(max_length = 20)
assignedTo = models.CharField(max_length = 30)
comments = models.TextField()
views.py
def opmStatistics(request):
"""
Return opmStatus page
"""
entries = posts.objects.all()#[:10] limits the number of entries
displayed
#opm_count = posts.objects.filter(posts.status=='Canceled').count()
#return render_to_response('opmStatistics.html', {'posts' :
opm_count})
return render_to_response('opmStatistics.html', {'posts' : entries})
My html code:
<tr><td>Current Number of Active Accelerator Operations OPMs: </td>
<td>
{% for post in posts %}
{% if post.status != "Canceled" %}
{% with OPM_count=forloop.counter %} <!-- how to save final number
as variable. -->
{{OPM_count}}
{% endwith %}
{% endif %}
{% endfor %}
</td>
</tr>
<br><br>
<tr><td>Current Number of Canceled Accelerator Operations OPMs: </td>
<td>
{% for post in posts %}
{% if post.status == "Canceled" %}
{% with OPM_count=forloop.counter %} <!-- how to save final
number as variable. this one does not reset to 1, starts where
it left off. -->
{{OPM_count}}
{% endwith %}
{% endif %}
{% endfor %}
</td>
</tr>
</table>
If you want to count a single value, then you should do that in the view. This is not at all something you should be attempting to do in the template.
You were almost there with your original attempt. It should be:
def opmStatistics(request):
"""
Return opmStatus page
"""
opm_count = posts.objects.filter(status='Canceled').count()
return render(request, 'opmStatistics.html', {'count': opm_count})
and then the template is just:
<tr>
<td>Current Number of Active Accelerator Operations OPMs: </td>
<td>{{ count }}</td>
</tr>
My aim is to create a matrix with individual editable fields. Since different people should only be allowed to edit certain fields I thought about creating an object called CellCE and an object level permission.
my models.py
class CellCE(models.Model):
row = models.ForeignKey('Descriptor',related_name='activecell', on_delete=models.CASCADE)
col = models.ForeignKey('Descriptor',related_name='passivecell', on_delete=models.CASCADE)
val = models.IntegerField(default=0)
project = models.ForeignKey('Project', on_delete=models.CASCADE, default='1')
#permission for Cells
class Meta:
permissions = (
("edit_cellCE", "Has permission to edit value of Cause and Effect cell"),
)
#classmethod
def create(cls, row, col, project):
CellCE = cls(row=row, col=col, project=project)
CellCE.save()
return CellCE
my views.py
def phase2(request, id):
projectname = get_object_or_404(Project, pk=id)
projectid = id
project = Project.objects.get (id=projectid)
projectdescriptors = Descriptor.objects.filter( project=projectid)
for Descriptor.id in projectdescriptors:
row = Descriptor.id
for Descriptor.id in projectdescriptors:
col = Descriptor.id
if CellCE.objects.filter(row=row, col=col, project=project).exists():
pass
else:
obj = CellCE.create(row, col, project)
CellCElist = CellCE.objects.filter(project= project)
context = {'CellCElist': CellCElist, 'projectname': projectname, 'projectid': projectid, 'projectdescriptors': projectdescriptors}
return render(request, 'szenario/phase2.html', context)
my template
<table>
{% for drow in projectdescriptors %}
{% if forloop.first %}
<tr>
<th align="left">Descriptors</th>
{% for value in projectdescriptors %}
<th>{{value}}</th>
{% endfor %}
</tr>
{% endif %}
<tr>
<th align="left">{{drow}}</th>
{% for dcol in projectdescriptors %}
<td align="center">
{% if forloop.parentloop.counter == forloop.counter %}
-
{% else %}
{% for CellCE in CellCElist %}
{% if CellCE.col == dcol %}
{% if CellCE.row == drow %}
Value =
{{CellCE.val}}
{% endif %}
{% endif %}
{% endfor %}
<form method="post">
{% csrf_token %}
<input type="submit" value="+1">
<input type="submit" value="-1">
</form>
{% endif %}
</td>
{% endfor %}
</tr>
{% endfor %}
</table>
The number of descriptors determins the size of the matrix. With every Descriptor over 15> loading the page takes longer or doesnt work at all. I am using SQLLite.
Question: How can I increase the loadingspeed and make this work at all? Does a change of DB solve the Problem or should i overthink my concept.
Any Help is appreciated.
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.
Hi guys,
I have this models:
class Pais(models.Model):
nome = models.CharField('Nome', max_length=50)
class Brinq(models.Model):
descricao = models.CharField('Nome', max_length=50)
class Filhos(models.Model):
nome = models.CharField('Nome', max_length=50)
idade = models.IntegerField('Idade')
pai = models.ForeignKey('Pais')
brinq = models.ForeignKey('Brinq', related_name='Brinq')
This view:
def editPai(request, idpai=None):
if idpai:
pai = Pais.objects.get(id=idpai)
else:
pai = None
ItensInlineFormSet = inlineformset_factory(Pais, Filhos, form=FilhosForm, extra=1)
formPais = PaisForm()
formsetItens = ItensInlineFormSet(instance=pai)
return render_to_response("base.html", {
"formPais": formPais, "formsetItens": formsetItens
}, context_instance=RequestContext(request), )
and this forms:
class PaisForm(ModelForm):
class Meta:
model = Pais
class FilhosForm(ModelForm):
class Meta:
model = Filhos
Ok, How can I get "descricao" value from "Brinq" model in my template? I think it's a simple question but, I tried looking, looking and looking again from internet and I don't find anything about this.
I start to thing it's not possible to do it using django, I want to believe that I'm wrong, but as I said, I didn't find anything about this in internet.
I try:
{% for form in formsetItens %}
<tr>
<td> {{ form.nome }}</td>
<td> {{ form.idade }}</td>
<td> {{ form.brinq__descricao }}</td>
</tr>
{% endfor %}
and {{ form.brinq.descricao}} to, and nothing... :(
Can anyone help me with this problem?
Regards,
You are trying to iterate over a FormSet. As the docs say "The formset gives you the ability to iterate over the forms in the formset and display them as you would with a regular form".
So you can for example do the following to display all the fields included in the form:
{% for form in formsetItens %}
{{ form.as_table }}
{% endfor %}
..or if it fits your use case you could wrap each form into a form tag, and loop over the form fields:
{% for form in formsetItens %}
<form action="/contact/" method="post">
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endfor %}
<p><input type="submit" value="Send message" /></p>
</form>
{% endfor %}