Show all items of an invoice - django - django

I would like to get all items belonging to an invoice and show them to a template without success. What i have done so far is the following:
I have two models:
class Invoice(models.Model):
PAYMENT_OPTIONS = (
('CASH', _('CASH')),
('DEPOSIT', _('DEPOSIT')),
('CARD', _('CARD')),
)
INVOICE_TYPE = (
('Service', _('Service')),
)
invoice_number = models.CharField(max_length=7, unique=True, default='INV4898')
invoice_user = models.ForeignKey(Account, on_delete=models.CASCADE)
invoice_type = models.CharField(max_length=30, choices=INVOICE_TYPE, default='Service')
payment_option = models.CharField(max_length=30, choices=PAYMENT_OPTIONS)
invoice_name = models.CharField(max_length=30, null=True, blank=True)
vat = models.CharField(max_length=9, blank=True, null=True)
gross_amount = models.DecimalField(max_digits=6, decimal_places=2)
vat_amount = models.DecimalField(max_digits=6, decimal_places=2)
net_amount = models.DecimalField(max_digits=6, decimal_places=2)
created_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.invoice_user.first_name} {self.invoice_user.last_name} - {self.invoice_number}"
class Item(models.Model):
invoice = models.ForeignKey(Invoice, related_name='items', on_delete=models.CASCADE)
title = models.CharField(max_length=255)
quantity = models.IntegerField(default=1)
unit_price = models.DecimalField(max_digits=6, decimal_places=2, default=Decimal('0.00'))
net_amount = models.DecimalField(max_digits=6, decimal_places=2, default=Decimal('0.00'))
vat_rate = models.CharField(max_length=10, default=0)
discount = models.DecimalField(max_digits=6, decimal_places=2, default=Decimal('0.00'))
is_paid = models.BooleanField(default=False)
created_date = models.DateTimeField(auto_now_add=True)
modified_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"{self.invoice.invoice_number}"
In the views.py i have a list view like, in which i'm trying to get a list of all invoices based on invoice_number and then match each invoice_number to an invoice in items. However using below code first pring brings all invoice_number(s) and second print brings all items for all invoices, not items per invoice.
def list_invoices(request, userprofile_id):
user_profile = get_object_or_404(Account, pk=userprofile_id)
all_invoices =Invoice.objects.filter(invoice_user=user_profile)
invoice_number = Invoice.objects.values_list('invoice_number')
print(invoice_number)
item_invoice = Item.objects.filter(invoice__invoice_number__in=invoice_number)
print(item_invoice)
context = {
'all_invoices': all_invoices,
'user_profile': user_profile,
'item_invoice': item_invoice,
}
return render(request, 'invoices/list-invoices.html', context)
I would appreciate any help.

You do not need to fetch the Items not the invoice_number of the Invoice. You only need to pass the invoices of the user_profile, and it might be better to also prefetch the Items:
def list_invoices(request, userprofile_id):
user_profile = get_object_or_404(Account, pk=userprofile_id)
all_invoices = Invoice.objects.filter(
invoice_user=user_profile
).prefetch_related('items')
context = {
'all_invoices': all_invoices,
'user_profile': user_profile
}
return render(request, 'invoices/list-invoices.html', context)
then in the template, you can access the .items, so:
<ul>
{% for invoice in all_invoices %}
<li> {{ invoice.invoice_number }}</li>
<ul>
{% for item in invoice.items.all %}
<li>{{ item.quantity }} {{ item.title }}</li>
{% endfor %}
</ul>
{% endfor %}
</ul>

Related

Django - How do I render a parent object in template?

I need to display some product's supplier, next to {{product.description}} but I can't get it to show on my table.
models.py
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)
def __str__(self):
return self.name
class Product(models.Model):
sku = models.IntegerField(null=True)
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)
image = models.ImageField(null=True, blank=True)
supplier = models.ForeignKey(Supplier, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.description
views.py
def products(request):
products = Product.objects.all()
suppliers = Supplier.objects.all()
context = {'products': products,
'suppliers': suppliers}
return render(request, 'crmapp/products.html', context)
products.html
<tr>
{% for product in products %}
<td>{{product.id}}</td>
<td><h6><strong>{{product.description}}</strong></h6></td>
<td >{{products.supplier}}</td>
<td>£{{product.costprice |floatformat:2}}</td>
<td>£{{product.retailprice |floatformat:2}}</td>
<td>{{product.barcode}}</td>
</tr>
{% endfor %}
Spelling mistake, I think.
<td >{{products.supplier}}</td>
Must be:
<td >{{product.supplier}}</td>
Notice I've removed the s in products.
Also, you don't need this in your views.py:
suppliers = Supplier.objects.all()
{{product.supplier}} will trigger a query to the db. To avoid that, use prefetch_related.
products = Product.objects.all().prefetch_related('supplier')
Note that this is optional. It will just improve efficency, but merely fixing the spelling mistake answers your question.

Django parent.child_set no errors but not showing in html

Views.py defining the context in view
def customers(request, pk):
customer = Customer.objects.get(id=pk)
issues = customer.issue_set.all()
receives = customer.receive_set.all()
context={'customer':customer,'issues':issues,'receives':receives}
return render(request,'accounts/customers.html')
in html
<div class="col-md">
<div class="card card-body">
<h5>Contact Information</h5>
<hr>
<p>Email: {{customer.email}}</p>
<p>Phone: {{customer.phone}}</p>
</div>
</div>
{% for issue in issues %}
<td>{{issue.item}}</td>>
<td>{{issue.item.category}}</td>
<td>{{issue.date_created}}</td>
<td>{{issue.status}}</td>
<td><a href="">UPDATE</td>
<td><a href="">DELETE</td>
{% endfor %}
#Model
class Item(models.Model):
CATEGORY = (
('Gudang Kering', 'Gudang Kering'),
('Gudang Basah','Gudang Basah'),
)
name = models.CharField(max_length=200,null= True)
stock = models.IntegerField(default='0', blank=False, null=True)
category = models.CharField(max_length=200,null= True,choices=CATEGORY)
reorderlevel = models.IntegerField(default='0', blank=False, null=True)
maxreorderlevel = models.IntegerField(default='0', blank=False, null=True)
description = models.CharField(max_length=200,null= True, blank= True)
date_created = models.DateTimeField(auto_now_add= True)
tags = models.ManyToManyField(Tag)
def __str__(self):
return self.name
class Issue(models.Model):
STATUS = (
('Pending', 'Pending'),
('Granted','Granted'),
('Denied','Denied'),
)
customer = models.ForeignKey(Customer, null=True, on_delete= models.SET_NULL)
item = models.ForeignKey(Item, null=True, on_delete= models.SET_NULL)
quantity = models.IntegerField(default='0', blank=False, null=True)
date_created = models.DateTimeField(auto_now_add=True, auto_now=False)
status = models.CharField(max_length=200,null= True, choices=STATUS)
def __str__(self):
return self.status + ' ' +str(self.customer)
I tried to get the object by id of the customer in order to make it a dynamic url where the url will depend on str:pk of customer id
i managed to show output data if i do
customer = Customer.objects.all #but that will show all the customer
so i tried as in the view to get the id
and define it with parent.child_set.all
but it doesn't show up,even the text update and delete don't show up in

django if in queryset is always false

class Product(models.Model):
title = models.CharField(max_length=120)
slug = models.SlugField(blank=True)
description = models.TextField()
price = models.DecimalField(decimal_places=2, max_digits=20, default=39.99)
image = models.ImageField(upload_to=upload_image_path,null=True, blank=True)
featured = models.BooleanField(default=False)
active = models.BooleanField(default=True)
timestamp = models.DateTimeField(auto_now_add=True)
class OrderItem(models.Model):
item = models.ForeignKey(Product, on_delete=models.CASCADE )
quantity = models.IntegerField(default=1)
item_cart = models.CharField(max_length=20, null=True, blank=True)
active = models.BooleanField(default=True)
class Cart(models.Model):
user = models.ForeignKey(User,null=True, blank=True,on_delete=models.CASCADE)
products = models.ManyToManyField(OrderItem, blank=True)
subtotal = models.DecimalField(default=0.00, max_digits=100, decimal_places=2)
total = models.DecimalField(default=0.00,max_digits=100,decimal_places=2)
updated = models.DateTimeField(auto_now=True)
timestamp = models.DateTimeField(auto_now_add=True)
"""
"""
def product_list_view(request):
queryset = Product.objects.all()
item = OrderItem.objects.all()
cart_obj, new_obj = Cart.objects.new_or_get(request)
print(item)
context = {
'product_list': queryset,
'cart' : cart_obj,
'orderitem' : item
}
return render(request, "products/list.html", context)
"""hmtl page list.hmtl
{% if obj in orderitem %} doesnt print else print allways
"""
{% for obj in product_list %}
<div class='col my-3'>
{{obj.title}}
{{obj.price}}
{{orderitem}}
{% if obj in orderitem %}
<h1>in cart</h1>
{% else %}
<h5>delete</h5>
{% endif %}
</div>
{% endor %}
orderitem = <QuerySet [<OrderItem: iphone 6s>, <OrderItem: hi>]>,
obj = hi ,
in list.hmtl if obj in orderitem always shows error and also tried obj.title in orderitem
But always else statement is printed without any error
trying to check the product is in ordereditem...

Django show extra content in class based view with ForeignKey models

I'm trying to add extra content to Djangos Class-based view to the template
I have some models like this
class District(models.Model):
district = models.CharField(max_length=255, null=False, unique=False, blank=True)
def __str__(self):
return self.district
class Street(models.Model):
street_name = models.CharField(max_length=255, null=False, unique=False, blank=True)
district = models.ForeignKey(District, verbose_name=_('district'), on_delete=models.CASCADE, null=True, blank=True)
zone = models.IntegerField(blank=True, null=True)
def __str__(self):
return self.street_name
class Article(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name="author", on_delete=models.SET_NULL)
timestamp = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=1, choices=STATUS, default=CREATED)
comment = models.CharField(max_length=255, null=True, unique=False, blank=True)
name = models.CharField(max_length=255, null=True, unique=False)
street = models.ForeignKey(Street, verbose_name=_('street'), on_delete=models.CASCADE, null=True, blank=True)
class ArticlesListView(LoginRequiredMixin, PermissionRequiredMixin,ListView):
model = Article
paginate_by = 50
context_object_name = "articles"
permission_required = 'is_staff'
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['Filter_name'] = Article.objects.order_by().values('name').distinct()
context['Filter_user'] = Article.objects.order_by().values('user').distinct()
return context
def get_queryset(self, **kwargs):
return Article.objects.all()
And late in the template
{% for f in Filter_name %}
<ul>
<li>{{f.name}}</li>
</ul>
{% endfor %}
How can I display a list of the district names and a list of the author names in the template with ForeignKey?
U can try something like that
{% for item in model_1.foreign_model_set.all %}
<h1>{{ item }}</h1>
{% endfor %}

Django odd boolean bahavior

I have a boolean field for whether or not an item is active:
is_active = models.BooleanField(default=True)
It seems pretty straightforward, my template will display items that are active:
{% for p in products|dictsortreversed:"id" %}
{% if p.is_active %}
<a href="{{ p.get_absolute_url }}">
{{ p.name }}
</a>
{% endif %}
For some reason all items are returned even if the field is 0 in the database. When I uncheck the boolean field in the django admin, it updates correctly to 0 in the database, but still shows as being checked in the admin...
It seems like django is reading the field as True, regardless of the boolean value.
Model
class Product(models.Model):
name = models.CharField(max_length=255, unique=True)
slug = models.SlugField(max_length=255, unique=True, help_text='Unique value for product page URL, created from name')
price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, default=0.00)
old_price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, default=0.00)
image = models.CharField(max_length=50)
is_active = models.BooleanField(default=True)
quantity = models.IntegerField()
description = models.TextField()
meta_keywords = models.CharField('Meta Keywords', max_length=255, help_text='Comma-delimited set of SEO keywords for meta tag')
meta_description = models.CharField('Meta Description', max_length=255, help_text='Content for description meta tag')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
categories = models.ForeignKey(Category, null=True)
publish_date = models.DateField(blank=True, null=True)
issue_one = models.CharField(blank=True, null=True, max_length=255)
issue_two = models.CharField(blank=True, null=True, max_length=255)
issue_three = models.CharField(blank=True, null=True, max_length=255)
class Meta:
db_table = 'products'
ordering = ['-created_at']
def __unicode__(self):
return self.name
#models.permalink
def get_absolute_url(self):
return ('catalog_product', (), {'product_slug': self.slug})
View:
def index(request, template_name="catalog/index.html"):
""" site home page """
page_title = 'Visible Language Ordering'
return render_to_response(template_name, locals(), context_instance=RequestContext(request))