So i have to render a table on html template which combines columns from 2 different base models. But the table doent seem to render well. Entries from other table are shown in different rows.
here is the screenshot of the table that has rendered
-I used the chain method from ittertools for this purpose. Not sure where I messed up.
Models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
image = models.ImageField(upload_to='profile_pics')
dob = models.DateField()
email = models.EmailField(max_length=50, unique=True)
class Placement(models.Model):
student = models.OneToOneField(User, on_delete=models.CASCADE)
company = models.CharField(max_length=40)
position = models.CharField(max_length=40)
city = models.CharField( max_length=40)
bond = models.CharField( max_length=40)
ctc = models.CharField( max_length=40)
my Views.py:
def mentorintern(request):
table = Placement.objects.all()
name_student = Profile.objects.all()
in_table = list(chain(table, name_student))
return render(request, 'mentorinternship.html', {'in_table': in_table })
HTML template used to render the table:
<table class="table align-items-center table-flush table-hover" id="dataTableHover">
<thead class="thead-light">
<tr>
<th>Name of Student</th>
<th>Company</th>
<th>Position</th>
<th>City</th>
<th>CTC</th>
<th>Bond</th>
</tr>
</thead>
<tbody>
{% for std in in_table %}
<tr>
<td>{{std.first_name}}</td>
<td>{{std.company}}</td>
<td>{{std.position}}</td>
<td>{{std.city}}</td>
<td>{{std.ctc}}</td>
<td>{{std.bond}}</td>
</tr>
{% endfor %}
</tbody>
</table>
What you're trying to do can be achieved easier than combining two query sets. Since you have a OneToOneField of User, you can directly access user details like this: {{std.student.first_name}}} inside the for loop. Now if I understand what you want, you probably need a foreign key of Profile table in Placement table. This way you can access, the profile as {{std.profile.first_name}} and the user table as {{std.profile.user.first_name}}.
Related
I want to count how many "plans" does a "client" have per table row in my template, there's a bit of the code
urls.py>>> urlpatterns = [ path('clients/', views.indexClient, name='clients'),]
models.py
class Plan (models.Model):
name = models.CharField(max_length=100, unique=True)
client = models.ForeignKey('Client', on_delete=models.RESTRICT)
gp_code = models.CharField(max_length=13, primary_key=True)
dispatch_conditions = models.TextField()
elaboration = models.CharField(max_length=100)
reviewer = models.CharField(max_length=100)
def __str__(self):
return self.product
------------------------------------------------------------------------------------
class Client (models.Model):
name = models.CharField(max_length=100, unique=True)
rif_num = models.CharField(max_length=10, primary_key=True)
def __str__(self):
return self.name
views.py
from django.db.models import Count
from .models import *
def indexClient(request):
client_list = Client.objects.all()
plans = Client.objects.annotate(num_plan = Count('plan'))
template = loader.get_template('app/clients.html')
context={'client_list':client_list, 'plans':plans}
return HttpResponse(template.render(context, request))
template clients.html
<table>
<thead>
<tr>
<th>Client</th>
<th >Plans</th>
</tr>
</thead>
<tbody>
{% for client in client_list %}
<tr>
<td>{{ client.name }}</td>
<td>{{ plans.num_plan }}</td>
</tr>
{% endfor %}
</tbody>
</table>
i tried to apply the methods said in this, this and this question but it didn't work for me or i'm applying the Count() incorrectly
want the table to display just like...
Client
Plans
Jhon
2
Mark
4
Louis
0
Vic
1
but currently the 'Plans' displays blank like this...
Client
Plans
Jhon
Mark
Louis
Vic
I am getting confused with the usage of related_name in django models, i know that the idea is to give me access to all the fields of a different table with foreignkey i am just not sure how to use it.
My model.py:
class Component(MPTTModel):
name = models.CharField(max_length=100)
manufacturer = models.CharField(max_length=100)
model = models.CharField(max_length=100)
serial_number = models.CharField(max_length=255)
price = models.IntegerField()
note = models.TextField()
image = models.ImageField(blank=True, null=True,
upload_to='components_imgs')
parent = TreeForeignKey("self", verbose_name=(
"Parent Component"), blank=True, null=True, related_name='children', on_delete=models.CASCADE)
def __str__(self):
return f"{self.id}, {self.name}"
class Job(models.Model):
job_type = (
('I', 'Interval'),
('O', 'One time'),
)
name = models.CharField(max_length=100)
description = models.CharField(max_length=100)
type = models.CharField(max_length=1, choices=job_type)
interval = models.IntegerField()
is_critical = models.BooleanField()
due_date = models.DateField()
component = models.ForeignKey(
Component, related_name='jobs', on_delete=models.CASCADE)
runninghours = models.ForeignKey(
RunningHours, related_name="RHjobs", on_delete=models.CASCADE)
def __str__(self):
return self.name
my view.py:
def worklist(request):
components = Component.objects.all()
Component_jobs = components.jobs.all()
context = {"component":components,
"Component_jobs":Component_jobs}
return render(request,"worklist.html",context)
I am trying to understand why these lines give me an error 'TreeQuerySet' object has no attribute 'jobs'
components = Component.objects.all()
Component_jobs = components.jobs.all()
but these lines work just fine,
component = Component.objects.all()
component_id = Component.objects.get(id=pk)
job_id = component_id.jobs.all()
are they not the same but with one i am getting all the jobs for a specific ID and the other i am getting all the jobs for all components?
Edited,
My template :
<div class="worklist">
{%for component in component %}
<p> {{component.name}} </p>
<div class="runninghours-table-flex">
<table class="runninghours-table">
<thead>
<tr>
<th>Job name</th>
<th>Job type</th>
<th>Due Date </th>
<th>Interval</th>
<th>Rank</th>
<th>Execute Job</th>
</tr>
</thead>
<tbody>
{% for c_jobs in component_jobs%}
<tr>
<td>{{c_jobs.name}} </td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
{%endfor%}
</tbody>
</table>
</div>
{%endfor%}
</div>
Assuming you want to display all components in a loop and then display all related jobs for each component in a nested loop, your template should look something like this simplified example
{% for component in components %}
{{ component }}
{% for job in component.jobs.all %}
{{ job }}
{% endfor %}
{% endfor %}
You should then use prefetch_related to fetch all related jobs for all components in a single query. There is no need to query the jobs in your view
components = Component.objects.all().prefetch_related('jobs')
As the error describes, this code returns a TreeQuerySet object.
components = Component.objects.all()
Trying to call fields like price will result in the same error.
components = Component.objects.all()
Component_jobs = components.price.all()
The reason this code works is because it is called on a specific Component instead of a collection of Components.
component = Component.objects.all()
component_id = Component.objects.get(id=pk)
job_id = component_id.jobs.all()
To get all jobs on a queryset, try using something like .values('jobs') from the queryset api reference
all_jobs = Component.objects.all().values('jobs')
I am working a Supplier Management System. I need to make a particular type of query which I am having issue implementing. I have the user models, and then the user_type which is of two types the suppliers and the admin. Of Course, the filter I need to implement is based of the supplier because only the supplier is able to create product in which they have to specify what categories as well.
My Problem: How can I get all categories a supplier products belongs to.
My Problem Edit: How can get each suppliers products and pass into the templates on the <td> tag
models.py
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True)
def get_email(self):
return self.email
class user_type(models.Model):
is_admin = models.BooleanField(default=False)
is_supplier = models.BooleanField(default=False)
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
if self.is_supplier == True:
return User.get_email(self.user) + " - is_supplier"
else:
return User.get_email(self.user) + " - is_admin"
#property
def get_categories(self):
return Category.objects.filter(product__user=self.id).distinct()
class Category(models.Model):
name = models.CharField(max_length=256)
def __str__(self):
return self.name
class Product(models.Model):
name = models.CharField(max_length=36)
price = models.PositiveIntegerField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.name
views.py
def Viewsupplier(request):
title = "All Suppliers"
suppliers = User.objects.filter(user_type__is_supplier=True)
categories = Category.objects.filter(product__user='2').distinct()
context = {"suppliers":suppliers, "title":title, "categories":categories}
return render(request, 'core/view-suppliers.html', context)
view-suppliers.html
<table class="table table-borderless table-data3">
<thead>
<tr>
<th>No</th>
<th>Email</th>
<th>Telephone</th>
<th>Category(s)</th>
<th>Country</th>
</tr>
</thead>
<tbody>
{% for supplier in suppliers %}
<tr>
<td>{{forloop.counter}}</td>
<td>{{supplier.email}}</td>
<td>{{supplier.telephone}}</td>
<td>{{supplier.get_categories}}</td>
<td>{{supplier.country}}</td>
</tr>
{% empty %}
<tr><td class="text-center p-5" colspan="7"><h4>No supplier available</h4></td></tr>
{% endfor %}
</tbody>
</table>
You can filter with:
Category.objects.filter(product__user=myuser).distinct()
where myuser is the user you want to filter on.
The .distinct(…) [Django-doc] will prevent returning the same Category that many times as there are Products for that user.
I have the following models:
class Supplier(models.Model):
name = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=200, null=True, blank=True)
email = models.CharField(max_length=200, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
ordering = ('name',)
def __str__(self):
return self.name
class Order(models.Model):
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.supplier.name
#property
def total(self):
orderitems = self.product_set.all()
total = sum([item.get_total for item in products])
return total
class Product(models.Model):
description = models.CharField(max_length=30)
costprice = models.FloatField(null=True, max_length=99, blank=True)
retailprice = models.FloatField(null=True, max_length=99, blank=True)
barcode = models.CharField(
null=True, max_length=99, unique=True, blank=True)
supplier = models.ForeignKey(
Supplier, on_delete=models.CASCADE, default=5)
on_order = models.ForeignKey(
Order, on_delete=models.CASCADE, null=True, blank=True)
on_order_quantity = models.FloatField(null=True, blank=True)
class Meta:
ordering = ('description',)
def __str__(self):
return self.description
i've created an order object for a given supplier with two products, with different quantities and cost prices.
How do I multiply cost x qty and add up those values in order to reach a total order value?
this is my view
def PurchaseOrder(request, pk_order):
orders = Order.objects.get(id=pk_order)
products = Product.objects.filter(
on_order_id=pk_order).prefetch_related('on_order')
total_products = products.count()
supplier = Product.objects.filter(
on_order_id=pk_order).prefetch_related('on_order')
total_value = Product.objects.filter(
on_order_id=pk_order).aggregate(Sum('costprice'))
context = {
'supplier': supplier,
'products': products,
'orders': orders,
'total_products': total_products,
'total_value': total_value, }
return render(request, 'crmapp/purchase_order.html', context)
at the moment it returns this:
This is my html template
It looks like your post is mostly code; please add some more details.'
Well, I need to show my code
{% extends 'crmapp/base.html' %}
{% load static %}
{% block content %}
<div class='main-site>'>
<h4> Supplier: {{orders.supplier}}</h4>
<h5>Order Number: {{orders.id}}</h5>
<h5>Created on: {{orders.date_created | date:"d/m/Y"}}</h5>
<h6>Total Lines In Order: {{total_products}}</h6>
<button style='margin-bottom:10px' class='btn btn-primary' id="open-popup-1">Edit</button>
<button style='margin-bottom:10px' class='btn btn-success' href="" id="open-popup-1">Print/Export</button>
<input type="search" placeholder="Search any field..." class="form-control search-input" data-table="customers-list"/>
<table class="table table js-sort-table mt32 customers-list" id='myTable'>
<thead class="table" >
<tr>
<th class='header' onclick="sortTable(0)" scope="col">ID</th>
<th class='header' onclick="sortTable(1)" scope="col">Description</th>
<th class='header' onclick="sortTable(3)" scope="col">Order Quantity</th>
<th class='header' onclick="sortTable(2)" scope="col">Cost</th>
</tr>
</thead>
<tbody>
<tr>
{% for product in products %}
<td> {{product.id}}</td>
<td><h6><strong>{{product.description}}</strong></h6></td>
<td>{{product.on_order_quantity |floatformat:0}}</td>
<td>£{{product.costprice |floatformat:2}}</td>
</tr>
</tbody>
{% endfor %}
</table>
<div class='ordertotal'>
<h5>Order Value:</h5>
<h6><strong>{{total_value}}</strong></h6>
</div>
</div>
{% endblock %}
Use the property decorator for the costprice field in the Product Model?
class Product(models.Model):
# define other fields here
#property
def costprice(self):
"Returns retailprice * qty for each product."
return self.on_order_quantity * self.retailprice
Update:
There's clearly some misunderstanding. Therefore I'll try to provide more information.
First Question: "How do I multiply cost x qty"
The property decorator allows you to create fields, which behave like calculated read_only fields. (You don't need to initialize them)
#property
def cost_x_qty(self):
"Returns costprice multiplied by qty for each product."
return self.on_order_quantity * self.costprice
Second Question: "How do I add up those values in order to reach a total order value?"
You can use Aggregation to do this.
You can do the following in your view function:
def PurchaseOrder(request, pk_order):
# some code
grand_total = Product.objects.filter(
on_order_id=pk_order).aggregate(Sum('cost_x_qty'))
# add to context
context['grand_total'] = grand_total
return render(request, 'some_template.html', context)
you can use the grand_total in your template file like this:
{{grant_total}}
Hope that helps
views.py
def add_phone(request):
phoneForm = PhoneForm()
if request.method=='POST':
phoneForm = PhoneForm(request.POST)
if phoneForm.is_valid():
phone=phoneForm.save(commit==False)
phone.user=request.user()
phone.save()
return redirect('/member/contact-list/')
return render_to_response('incident/add_phone.html',
{
'about_menu': True,
'PhoneForm' :phoneForm
},
context_instance=RequestContext(request))
template.py
<form action="/member/add-phone/" method="POST"> {% csrf_token %}
<table width="100%" cellpadding="0" cellspacing="0" id="phone">
<tr>
<td colspan="2"><h1 align="left">Call - default telephone numbers</h1></td>
</tr>
<tr>
<td colspan="2">Set the phone numbers that people should use if they <br />
need back-up in dealing with an incident.
</td>
</tr>
<tr>
<td>Person or area</td>
<td>Phone number</td>
</tr>
<tr>
<td>{{PhoneForm.number1}}</td>
<td>{{PhoneForm.number1}}</td>
</tr>
<tr>
<td>{{PhoneForm.name2}}</td>
<td>{{PhoneForm.number2}}</td>
</tr>
<tr>
<td>{{PhoneForm.name3}}</td>
<td>{{PhoneForm.number3}}</td>
</tr>
<tr>
<td>Emergency</td><td>Phone number</td>
</tr>
<tr>
<td>{{PhoneForm.emergency}}</td>
<td>{{PhoneForm.emergency_number}}</td>
</tr>
<tr><td colspan="2" align="right"> <p style=margin-top:2cm;>{% include "buttons/save.html" %}</p></td></tr>
</table></form>
forms.py
class PhoneForm(forms.ModelForm):
class Meta:
model = Phone_info
models.py
class Phone_info(models.Model):
user = models.ForeignKey(User, null=True)
name1 = models.CharField('Name', max_length=100, null=True, blank=True)
number1 = models.CharField('Number',max_length=20, null=True, blank=True)
name2 = models.CharField('Name', max_length=100, null=True, blank=True)
number2 = models.CharField('Number', max_length=20, null=True, blank=True)
name3 = models.CharField('Name', max_length=100, null=True, blank=True)
number3 = models.CharField('Number',max_length=20, null=True, blank=True)
emergency = models.CharField('Emergency', max_length=100, null=True, blank=True)
emergency_number = models.CharField('Emergency Number',max_length=20, null=True, blank=True)
I am using models form,while clicking save button page gets navigate but what ever datas i am entering not saving in database.
Thanks
You have this line when you assign the phone's user:
phone.user=request.user()
but it should be without the parenthesis because request.user is not callable. Correct it like this:
phone.user=request.user
and give it a try. Your code seems well.
Also, form is probably not validating because you have to add blank=True to the user's field declaration in the models just like this:
user = models.ForeignKey(User, null=True, blank=True)
Hope it helps.
while clicking save button page gets navigate but what ever datas i am
entering not saving in database.
This is because you don't have an else condition to match your phoneForm.is_valid() and since your redirect is part of the outer if, the page always redirects even if the form doesn't validate.
Try this version:
from django.shortcuts import render
def add_phone(request):
""" Responds to /member/contact-list/ and
adds a phone to the database """
phoneForm = PhoneForm()
if request.method=='POST':
phoneForm = PhoneForm(request.POST)
if phoneForm.is_valid():
phone=phoneForm.save(commit=False)
phone.user=request.user
phone.save()
return redirect('/member/contact-list/')
else:
# Form didn't validate
return render(request,
'incident/add_phone.html',
{'PhoneForm': phoneForm,
'about_menu': True})
return render(request,
'incident/add_phone.html',
{'about_menu': True, 'PhoneForm': phoneForm})
In your template, make sure you are displaying any errors from the form. See this section of the manual on how to customize the error output in your templates.