I have two models;
class Customer(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
email = models.EmailField()
class WorkOrder(models.Model):
date_created = models.DateField('Date', default=datetime.now)
due_date = models.DateField('Due Date')
customer = models.ForeignKey(Customer, on_delete=models.CASCADE, verbose_name='Customer')
STATUS_CHOICES = [
('pending', 'Pending'),
('approved', 'Approved'),
('completed', 'Completed'),
('cancelled', 'Cancelled'),
]
status = models.CharField('Status of the work order', max_length=10, choices=STATUS_CHOICES, default='pending')
description = models.TextField('Description of the work')
I wrote a class based list view to make a customer list:
class ReportCustomerListView(ListView):
model = CustomUser
template_name = 'reports/customer_report.html'
def get_queryset(self):
return CustomUser.objects.filter(is_staff=False).filter(is_superuser=False)
I would like to prepare a report for the user about its customers so I wanted to show how many pending, approved and completed work orders a customer have. My list template is;
<table class="table table-striped">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First Name</th>
<th scope="col">Last Name</th>
<th scope="col">Company</th>
<th scope="col">Pending Work Orders</th>
<th scope="col">Active Work Orders</th>
<th scope="col">Completed Work Orders</th>
<th scope="col">Draft Bills</th>
</tr>
</thead>
<tbody>
{% for customer in object_list %}
<tr>
<th scope="row">{{ forloop.counter }}</th>
<td>{{ customer.first_name }}</td>
<td>{{ customer.last_name }}</td>
<td>{{ customer.company.company_name }}</td>
...
...
... // the part where I am stuck
But I am lost after that after 4 hours of reading I am more confused. I know I can access work orders from
>>> Users.objects.get(pk=pk).workorder_set
My question is how can I get the customers work orders counts on each status types on the template? In other words how can I filter the related fields on the objects list on template?
Other methods such as filtering on views would also work for me but again I don't know how to do it.
Thank you very much for your time...
if you want to get your related objects then you should try this django-taggit install in your app and try this code...
views.py
def tagged(request, slug):
tag = get_object_or_404(Tag, slug=slug)
# Filter posts by tag name
posts = Post.objects.filter(tags=tag)
context = {
'tag':tag,
'posts':posts,
}
Related
app1/model
class Deployment(models.Model):
uid = models.CharField(max_length=255, blank=True)
target = models.CharField(max_length=255)
name = models.CharField(max_length=255, blank=True)
description = models.TextField(blank=True)
app2/model
class AccountRecord(models.Model):
name = models.CharField(max_length=255, blank=True)
file_name = models.CharField(max_length=255, blank=True)
national_id = models.CharField(max_length=255, default="")
app3/views.py
class IndexView(LoginRequiredMixin, ListView):
model = AccountRecord
template_name = "tableview/table_view.html"
paginate_by = 25
def get_context_data(self, **kwargs):
context = super(IndexView, self).get_context_data(**kwargs)
context['deployment'] = Deployment.objects.all()
return context
app3 html template
<table class="table card-table table-vcenter text-nowrap">
<thead>
<tr>
<th>Deployment</th>
<th>Account</th>
<th>National ID</th>
<th>Filename</th>
</tr>
</thead>
<tbody>
{% for account in object_list %}
<tr>
<td>DEPLOYMENT.NAME HERE!</td>
<td>{{ account.name }}</td>
<td>{{ account.national_id }}</td>
<td>{{ account.file_name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
I am trying to pass data from these 2 model to another apps html template.
with my current app3/views.py the table only show blank column even after i put {{ deployment.name }}
can anyone point out how to do it correctly.
I have been stucked on this for a couple of days, all help would be really cherished.
I have a list and detail view which are function based views, my detail view works perfectly because i am able to pass the "/str:pk/" at the end of the url and also with the request as(def po_detail(request, pk)) which in turn i am able to pass into my view functions and they all successfully return the unique id i desire.
I have a custom queryset i have written to help me get the sum total amount of some payments and return it in both the list and detail view.
The issues now is that i am not able to get each unique items in my list view page because i am not able to pass the pk into the url and the request function as the object i used it for in detail function has access to the pk.
I have id=True so as to prevent error, because when i made id=id, it gave me a error saying, "Field 'id' expected a number but got ."
The image is pictorial representation of the list template which output both the payment amount and the balance of only the first id instead of the individual id as opposed in the detail template.
This is the image of the detail template which works well as well as for other id
I would love if any one can provide an hint, suggestion, or solution.
Thanks,
Oyero H.O
Below is my model
class PurchaseOrder(models.Model):
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
po_type = models.ForeignKey(PurchaseOrderType, on_delete=models.SET_NULL, null=True)
status = models.CharField(choices=STATUS, max_length=15)
supplier_ID = models.ForeignKey(Supplier, on_delete=models.SET_NULL, null=True)
order_date = models.DateField()
desired_ship_date = models.DateField()
ready_date = models.DateField()
po_amount = models.IntegerField()
def __str__(self):
return str(self.id)
class PurchaseOrderPayment(models.Model):
po_number = models.ForeignKey(PurchaseOrder, on_delete=models.SET_NULL, null=True)
date = models.DateField()
amount = models.IntegerField()
memo = models.CharField(max_length=200)
def __str__(self):
return self.memo
Below is my view function
#login_required(redirect_field_name='po_list')
def po_list(request):
po_lists = PurchaseOrder.objects.all()
po_detail = PurchaseOrder.objects.get(id=True)
payment_lists_doc = PurchaseOrderPayment.objects.filter(po_number__id=True)
amount = po_detail.po_amount
paid_amount = PurchaseOrderPayment.objects.filter(po_number=po_detail).aggregate(Sum('amount'))['amount__sum']
balance = amount - paid_amount
context = {'po_lists':po_lists, 'payment_lists_doc':payment_lists_doc,
'amount':amount, 'paid_amount':paid_amount, 'balance':balance,
'payment_lists_doc':payment_lists_doc
}
return render(request, 'dashboard/po_list.html', context)
#login_required(redirect_field_name='po_detail')
def po_detail(request, pk):
po_detail = PurchaseOrder.objects.get(id=pk)
payment_lists_doc = PurchaseOrderPayment.objects.filter(po_number__id=pk)
document_lists_doc = PurchaseOrderDocument.objects.filter(po_number__id=pk)
amount = po_detail.po_amount
paid_amount = PurchaseOrderPayment.objects.filter(po_number=po_detail).aggregate(Sum('amount'))['amount__sum']
balance = amount - paid_amount
context = {'po_detail':po_detail, 'payment_lists_doc':payment_lists_doc,
'payment_form':payment_form, 'document_form':document_form,
'document_lists_doc':document_lists_doc,
'paid_amount':paid_amount,
'balance':balance, 'amount':amount}
return render(request, 'dashboard/po_detail.html', context)
This is my list template
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>CREATED</th>
<th>TYPE</th>
<th>STATUS</th>
<th>SUPPLIER NAME</th>
<th>ORDER DATE</th>
<th>AMOUNT</th>
<th>PAID AMOUNT</th>
<th>BALANCE AMOUNT</th>
</tr>
</thead>
<tbody>
{% for po_list in po_lists %}
<tr>
<td style="cursor: pointer;">{{po_list.id}}</td>
<td>{{po_list.created_on}}</td>
<td>{{po_list.po_type}}</td>
<td>{{po_list.status}}</td>
<td>{{po_list.supplier_ID}}</td>
<td>{{po_list.order_date}}</td>
<td>{{po_list.po_amount}}</td>
<td data-toggle="modal" data-target="#paid_amount_modal" style="cursor: pointer;">
{{paid_amount}}
</td>
<td>{{balance}}</td>
</tr>
{% endfor %}
</tbody>
</table>
And lastly, my detail template
<table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
<thead>
<tr>
<th>ID</th>
<th>CREATED</th>
<th>TYPE</th>
<th>STATUS</th>
<th>SUPPLIER NAME</th>
<th>ORDER DATE</th>
<th>AMOUNT</th>
<th>PAID AMOUNT</th>
<th>BALANCE AMOUNT</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{po_detail.id}}</td>
<td>{{po_detail.created_on}}</td>
<td>{{po_detail.po_type}}</td>
<td>{{po_detail.status}}</td>
<td>{{po_detail.supplier_ID}}</td>
<td>{{po_detail.order_date}}</td>
<td>{{po_detail.po_amount}}</td>
<td>{{paid_amount}}</td>
<td>{{balance}}</td>
</tr>
</tbody>
<div></div>
</table>
This is how to do it,
screenshot included,
mark my answer if that helped.
Edit your models.py
class PurchaseOrder(models.Model):
...
#property
def get_payments_sum(self):
return sum(item.get_amount for item in self.items.all())
#property
def get_balance(self):
return self.get_payments_sum - self.po_amount
class PurchaseOrderPayment(models.Model):
po_number = models.ForeignKey(PurchaseOrder, on_delete=models.SET_NULL, null=True, related_name="items")
...
#property
def get_amount(self):
return self.amount
views.py
note that i only edited as to fix your issue (sum and balance), so you have to add whatever else remaining in context like "payment_lists_doc"
def po_list(request):
po_lists = PurchaseOrder.objects.all()
context = {'po_lists':po_lists}
return render(request, 'dashboard/po_list.html', context)
po_lists.html
<tbody>
{% for po_list in po_lists %}
<tr>
<td style="cursor: pointer;">{{po_list.id}}</td>
<td>{{po_list.created_on}}</td>
<td>{{po_list.po_type}}</td>
<td>{{po_list.status}}</td>
<td>{{po_list.order_date}}</td>
<td>{{po_list.po_amount}}</td>
<td data-toggle="modal" data-target="#paid_amount_modal" style="cursor: pointer;">
{{po_list.get_payments_sum}}
</td>
<td>{{po_list.get_balance}}</td>
</tr>
{% endfor %}
</tbody>
enter image description here
First, fix your error
po_detail = PurchaseOrder.objects.get(id=True)
payment_lists_doc =
PurchaseOrderPayment.objects.filter(po_number__id=True)
amount = po_detail.po_amount = True
You need to pass an id (integer) to these fields
Item Model (represents a product, like a MacBook)
class Item(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=100)
manufacturer = models.ForeignKey('Manufacturer', blank=True, null=True, on_delete=models.SET_NULL)
introduction = models.DateField(auto_now=True)
is_retired = models.BooleanField(default=False)
tags = models.ManyToManyField(Tag)
def __str__(self):
return self.name
OnHand Model (represents a serialized MacBook)
class OnHand(models.Model):
name = models.CharField(max_length=100)
serial = models.CharField(max_length=80)
asset = models.CharField(max_length=20)
product = models.ForeignKey(Item, blank=True, null=True, on_delete=models.CASCADE)
tags = models.ManyToManyField(Tag)
def __str__(self):
return self.serial
Index View
Index Function
def index(request):
items = Item.objects.all()
context = {
'items':items,
}
print(items)
return render(request, 'index.html', context)
Template/Table
<table class="table table-hover">
<thead class="thead-light">
<tr>
<th>Item Id</th>
<th>Title</th>
<th>Manufacturer</th>
<th>On Hand</th>
<th>Category Id</th>
</tr>
</thead>
<tbody>
{% for item in items %}
<tr>
<td>{{ item.pk }}</td>
<td>{{ item.name }}</td>
<td>{{ item.manufacturer }}</td>
<td>{{ item.quanity }}</td>
</tr>
{% endfor %}
</tbody>
</table>
This application is an Inventory Management System which can take in Items such as a MacBook Pro or iPhone 6, and OnHands which are serialized instances of these Items. In my Index Function I am passing the result of an all() query to the Index View in context.
I can query OnHand.objects.filter(product_id=item.pk) to get the quanity of each Item, however, in my current way of doing things I'm unsure how I can pass that value to the front end while keeping its relationship if that makes sense.
I would like item.quanity to essentially represent the quanity of that particular item. What am I looking for? My initial thought would be to append to the QuerySet but I'm not sure how to do so.
You're looking for annotate.
from django.db.models import Count
items = Item.objects.annotate(
quantity=Count('onhand_set__id'),
)
Depending on your usage, you may need to pass distinct=True to Count.
I am trying to show a table of schools in a cluster(city or town) in a descending order with respect to school average marks.
<table class="table">
<thead>
<tr>
<th>School</th>
<th>Strength</th>
<th>Average</th>
</tr>
</thead>
<tbody>
{% for school in school_order %}
<tr>
<td>{{ school.school_name }}</td>
<td>{{ school.strength }}</td>
<td>{{ school.get_average }}</td>
</tr>
{% endfor %}
</tbody>
</table>
This is the table I'm trying to display in my template
school_order = cluster.school_set.all().order_by('-get_average')
This is how I'm trying to get school_order in view.py
get_average is not a field for model school but it is a method I used in the model.
class School(models.Model):
state = models.ForeignKey(State, on_delete=models.CASCADE)
region = ChainedForeignKey(Region, chained_field="state",chained_model_field="state", show_all=False, auto_choose=True, sort=False, on_delete=models.CASCADE)
cluster = ChainedForeignKey(Cluster, chained_field="region",chained_model_field="region", show_all=False, auto_choose=True, sort=False, on_delete=models.CASCADE)
school_name = models.CharField(max_length=250)
facilitator = models.CharField(max_length=250)
f_number = models.IntegerField()
f_email = models.EmailField()
school_logo = models.FileField(default='')
strength = models.IntegerField()
def get_average(self):
return self.avergae_set.latest('average_date').average_value
This is my model for school.
The error I'm getting is cannot resolve keyword 'get_average' into field.
Please help!
You can't use Django ORM's orderby for non model field. You can convert the queryset to list and do sort in python.
school_order = list(cluster.school_set.all())
.sort(key=lambda x: x.get_average, reverse=True)
Other options are you can you select extra or annotate.
Ref: https://docs.djangoproject.com/en/1.11/ref/models/querysets/#annotate
I am iterating through a queryset in the template using template tags to show the data of existing database entries (i.e. Product Details of each product in a customer order). However, I want to show users some values (i.e. quantity and price) that are located in an intermediate m2m model between the Product and Order models for each product in the order.
My approach was to create the querysets in views and pass them through context into the template but I cannot seem to 'call' the values at the template using template tags for the intermediate m2m data. Perhaps my context is passing the wrong queryset or my approach is just wrong.
My code is below and I am thankful for any help you can give:
Models.py Snippet
class Product(models.Model):
article_number = models.ForeignKey('Article_number')
color = models.ForeignKey('Color')
size = models.ForeignKey('Size')
barcode = models.ForeignKey('Barcode')
product_name = models.ForeignKey('Product_name')
brand = models.ForeignKey('Brand')
category = models.ForeignKey('Category')
manufacturer = models.ForeignKey('Manufacturer')
cost_currency = models.ForeignKey('Cost_Currency', null=True, blank=True)
cost_price = models.DecimalField(decimal_places=2, max_digits=10)
selling_currency = models.ForeignKey('Selling_Currency', null=True, blank=True)
selling_price = models.DecimalField(decimal_places=2, max_digits=10)
description = models.TextField(null=True, blank=True)
created_on = models.DateTimeField(auto_now_add=True, auto_now=False)
updated_on = models.DateTimeField(auto_now_add=False, auto_now=True)
last_edited_by = models.ForeignKey(User, null=True, blank=True)
active = models.BooleanField(default=True)
class Meta:
unique_together = (("article_number", "size", "color"))
verbose_name = "Product"
verbose_name_plural = "*Products*"
def __unicode__(self):
return str(self.article_number) + "-" + str(self.color) + "-" + str(self.size)
class Order(models.Model):
order_status = models.ForeignKey('OrderStatus')
products = models.ManyToManyField(Product, through='OrderProductDetails', through_fields=('order','product'), null=True, blank=True)
counter = models.ForeignKey(Counter, null=True, blank=True)
order_type = models.ForeignKey('OrderType')
order_remarks = models.CharField(max_length=1000, null=True, blank=True)
order_date = models.DateTimeField(auto_now_add=True, auto_now=False)
ordered_by = models.ForeignKey(User, null=True, blank=True)
promo = models.ForeignKey('promo.Promo', verbose_name="Order for which Promotion (if applicable)", null=True, blank=True)
delivery_date = models.DateField(blank=True, null=True)
delivery_remarks = models.CharField(max_length=1000, null=True, blank=True)
updated_on = models.DateTimeField(auto_now_add=False, auto_now=True)
class Meta:
verbose_name = "Order"
verbose_name_plural = "*Orders*"
def __unicode__(self):
return str(self.id)
class OrderProductDetails(models.Model):
order = models.ForeignKey('Order')
product = models.ForeignKey('products.Product')
quantity = models.PositiveIntegerField()
selling_price = models.DecimalField(decimal_places=2, max_digits=10)
order_product_remarks = models.ForeignKey('OrderProductRemarks',blank=True, null=True)
class Meta:
verbose_name_plural = "Order - Product Details"
verbose_name = "Order - Product Details"
def __unicode__(self):
return str(self.id)
Views.py Snippet
from django.shortcuts import render, Http404, HttpResponseRedirect
from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib import messages
from django.forms.models import modelformset_factory
from orders.models import Order, OrderStatus, OrderProductDetails
#login_required(login_url='/admin/login/?next=/')
def warehouseOrder(request, id):
try:
order = Order.objects.get(id=id)
products = order.products.all()
orderDetails = OrderProductDetails.objects.filter(order__id=id)
context = {'order': order, 'products': products, 'orderDetails': orderDetails}
template = 'warehouse_order.html'
return render(request, template, context)
except:
raise Http404
Template.html Snippet
<table class="table table-striped table-bordered">
<tr>
<th class="bottom-align-th">#</th>
<th class="bottom-align-th">Article No.</th>
<th class="bottom-align-th">Color</th>
<th class="bottom-align-th">Size</th>
<th class="bottom-align-th">Quantity</th>
<th class="bottom-align-th">Unit Price</th>
<th class="bottom-align-th">Remarks</th>
<th class="bottom-align-th">Barcode No.</th>
<th class="bottom-align-th">Packed</th>
</tr>
{% for product in products %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ product.article_number }}</td>
<td>{{ product.color }}</td>
<td>{{ product.size }}</td>
<td>{{ orderDetails.quantity }}</td>
<td>{{ orderDetails.selling_price }}</td>
<td>{{ orderDetails.order_product_remarks }}</td>
<td>{{ product.barcode }}</td>
<td><input type="checkbox" id="large-checkbox"></td>
</tr>
{% endfor %}
</table>
Btw, using Django 1.7.2 here.
You're looping over the wrong thing. Each Order has multiple OrderProductDetails related objects, each of which has exactly one Product. But you're looping over all products. Try something like:
{% for detail in orderDetails %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ detail.product.article_number }}</td>
<td>{{ detail.product.color }}</td>
<td>{{ detail.product.size }}</td>
<td>{{ detail.quantity }}</td>
<td>{{ detail.selling_price }}</td>
<td>{{ detail.order_product_remarks }}</td>
<td>{{ detail.product.barcode }}</td>
<td><input type="checkbox" id="large-checkbox"></td>
</tr>
{% endfor %}