if statement and for loop problem in django html - python

I am trying to print all the orders related to a specific customer. I used a for loop to access my orders in the html file, and i used an if statement to make sure that the order is related to the customer.
{% for order in orders %}
{% if customer.name == order %}
{{ order }}
{% endif %}
{% endfor %}
in my views I gave my html file access to these variables.
def orderss(request, pk):
Customer = customer.objects.get(id=pk)
orders = Order.objects.all()
context = {
'customer':Customer,
'orders': orders,
}
return render(request, 'Inventory_Management/orders.html', context)
to reach this page i used a button
View Orders
the url is the one below
path('orders/<str:pk>/', orderss, name="orderss")
related models
class Order(models.Model):
STATUS = (
('Pending', 'Pending'),
('Out for delivery', 'Out for delivery'),
('Delivered', 'Delivered'),
)
order_head = models.ForeignKey(order_header, blank=False, null=True, on_delete=models.SET_NULL)
items = models.ForeignKey(item, blank=False, null=True, on_delete=models.SET_NULL)
Quantity = models.CharField(max_length=100)
date_created = models.DateTimeField(auto_now_add=True, null=True)
total = models.CharField(max_length=100)
status = models.CharField(max_length=200, null=True, choices=STATUS)
def __str__(self):
return '{self.order_head.Buyer}'.format(self=self)
class customer(models.Model):
name = models.CharField(max_length=12, blank=False)
phone = models.CharField(max_length=12, blank=False)
email = models.CharField(max_length=50, blank=False)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return self.name
class order_header(models.Model):
date_created = models.DateTimeField(auto_now_add=True, null=True)
User = models.CharField(max_length=100, blank=False, default="Seller")
Type = models.CharField(max_length=100, default="cash")
Buyer = models.ForeignKey(customer, blank=True, null=True, on_delete=models.SET_NULL)
Note = models.CharField(max_length=100, blank=True, default="Discount: ")
Order_Id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
def __str__(self):
return 'Order Customer: {self.Buyer}, Order Id: {self.Order_Id}'.format(self=self)
now the problem is no orders appear when I press the button, all i get is a blank page even though the specific customer has a number of orders. Help appreciated! Please Help!

In template you're trying to compare name field that is string with object (Order). I guess you thought that name will be compared with order string representation using __str__ method.
Try this:
views.py
Customer = customer.objects.get(id=pk)
orders = order_header.objects.filter(Buyer=Customer)
context = {'orders': orders}
template
{% for order_head in orders %}
{% for order in order_head.order_set.all %}
{{ order }}
{% endfor %}
{% endfor %}

Related

Django I can't pull data from database

Admin can change the web title,keywords or description. But it's not working rn. When i entry website everything is fine i don't have any error but informations didn't come from database.
This is my home/models.py
from django.db import models
class Setting(models.Model):
title = models.CharField(max_length=150)
keywords = models.CharField(max_length=255)
description = models.CharField(max_length=255)
company = models.CharField(max_length=50)
address = models.CharField(blank=True, max_length=150)
phone = models.CharField(blank=True, max_length=15)
fax = models.CharField(blank=True, max_length=15)
email = models.CharField(blank=True, max_length=50)
smptpserver = models.CharField(blank=True, max_length=30)
smptemail = models.CharField(blank=True, max_length=30)
smptpassword = models.CharField(blank=True, max_length=150)
smptport = models.CharField(blank=True, max_length=15)
icon = models.ImageField(blank=True, upload_to='images/')
facebook = models.CharField(blank=True, max_length=50)
instagram = models.CharField(blank=True, max_length=50)
twitter = models.CharField(blank=True, max_length=50)
aboutus = models.CharField(max_length=50)
contact = models.CharField(max_length=50)
contact_map = models.CharField(max_length=50)
references = models.CharField(max_length=50)
status = models.CharField(max_length=10, choices=STATUS)
create_at = models.DateTimeField(auto_now_add=True)
uptade_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
This is my home/views.py
from django.http import HttpResponse
from django.shortcuts import render
from home.models import Setting
def index(request):
setting=Setting.objects.all()
context={'setting':setting}
return render(request,'index.html',context)
This is my home/temp/index.html
{% block title %} {{ setting.title }} {% endblock %}
{% block keywords %} {{ setting.keywords }} {% endblock %}
{% block description %} {{ setting.description }} {% endblock %}
Your issue is that you're returning a whole queryset, not a single item
setting=Setting.objects.all()
context={'setting':setting}
If you only ever have one Setting record, you could use Setting.objects.first() instead. If you have more than one you should use Setting.objects.get(...) to retrieve a single record.
You can see this for yourself if you examine the value of setting in the view before you return it (use a breakpoint() to look at the vars in the shell, or just print it out).
As long as you use all() the template will be expecting an iterable of objects for you to loop over - that iterable will not have properties like keywords, description etc.

Reverse query in Django Many to Many

I have a problem in django reverse many to many. Basically, I think I am missing something that I couldn't understand properly yet.
I have these models and views.
models.py
class TheorySyllabus(models.Model):
name = models.CharField(max_length=100, null=True, blank=True)
subject_duration = models.ManyToManyField(
SubjectDuration, related_name='subject_durations')
course_type = models.ForeignKey(
CourseType, on_delete=models.DO_NOTHING, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class Meta:
verbose_name_plural = 'Theory Syllabus'
class TheoryCourse(models.Model):
name = models.CharField(max_length=100)
student = models.ManyToManyField(Student, related_name='theory_courses')
theory_syllabus = models.ForeignKey(
TheorySyllabus, on_delete=models.DO_NOTHING, null=True, blank=True)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.name
class Student(models.Model):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
date_of_birth = models.DateField()
fiscal_code = models.CharField(max_length=50)
phone = models.CharField(max_length=50)
license = models.ForeignKey(
License, on_delete=models.PROTECT, blank=True, null=True)
picture = models.ImageField(
blank=True, null=True, default='default.png')
id_card = models.ForeignKey(
IDCard, on_delete=models.PROTECT, blank=True, null=True)
address = models.CharField(max_length=100)
cap = models.CharField(max_length=10)
city = models.CharField(max_length=100)
province = models.CharField(max_length=100)
country = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.user.first_name + ' ' + self.user.last_name
views.py
class CourseListView(ListView):
model = TheoryCourse
queryset = TheoryCourse.objects.filter(
is_active=True).order_by('-created_at')
template_name = 'theory/course_list.html'
context_object_name = 'theory_courses'
paginate_by = 10
template
<div class="card-body table-responsive p-0">
<table class="table table-hover text-nowrap table-bordered">
<thead>
<tr>
<th>Course Type</th>
<th>Course Name</th>
</tr>
</thead>
<tbody>
{% for course in theory_courses %}
<tr>
<td>{{course.theory_syllabus.name}}</td>
<td>{{course.name}}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
What I need to do, is to retrieve the total number of students that are in each TheoryCourse model. But I really have no idea how to use the reverse relationship.
I tried to use that in the template with something like:
{% for student in theory_courses.students.all %}
{% endfor %}
But, it's not working. I read all the django documentation but either I didn't understand something or I am doing something wrong.
Any help would be appreciated
So, you have student in your model, not students. Thus for will look something like this
{% for student in theory_courses.student.all %}
{% endfor%}
Furthermore, if you want to get only count, you can just use
{% for student_count in theory_courses.student.count %}
{% endfor %}
P.S. That has nothing to do with reverse (related_name) in many to many. related name just means that you can access your TheoryCourse model from Student with Student.theory_courses

Uable to get the product name from the model

I've create 3 models for the Order processing. However, I couldn't show the product name on template for every single order. Does my for loop logic or 'get' method go wrong?
models.py:
class Product(models.Model):
product_name = models.CharField(max_length=200)
price = models.DecimalField(decimal_places=2, max_digits=10, blank=True)
created = models.DateTimeField(auto_now=True)
slug = models.SlugField(max_length=255, unique=True)
def __str__(self):
return self.product_name
class OrderItem(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True)
item = models.ForeignKey(Product, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
ordered = models.BooleanField(default=False)
def __str__(self):
return f"{self.quantity} of {self.item.product_name}"
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, blank=True, null=True)
items = models.ManyToManyField(OrderItem)
start_date = models.DateTimeField(auto_now_add=True)
ordered = models.BooleanField(default=False)
def __str__(self):
return self.user.username
view.py:
def user_info(request):
orders = Order.objects.filter(user=request.user, ordered=True).order_by('-start_date')
context = {
'orders': orders,
}
return render(request, 'home.html', context)
home.html:
{% for order_item in orders.items.all %}
<p>{{ order_item.item.product_name }}</p>
{% endfor %}
You are passing orders from your view which is a queryset so you can't do orders.items.all. You should do a for loop to loop over orders and then get the items:
{% for order_item in orders %}
<p>product names for order id {{order_itme.id}}:</p>
{% for item in order_item.items.all %}
<p>{{ item.item.product_name }}</p>
{% endfor %}
{% endfor %}
Note that this will renders all items for all orders. You should filter the result if you just need one or some of them.

How do i display billing address for each product that has been successfully delivered to a customer/user

I was able to create a billing address using form, now i want to display the billing address in the customer's account (Order product). so when the customers want to check the information of all the product they have ordered, i want them to also see the billing address for each of the product, for example if they also uses a different billing addresses. I was able to get the address displayed on template, but it address gets duplicated on template, instead of displaying only the address for each product ordered.
class Order(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
items = models.ManyToManyField(OrderItem)
start_date = models.DateTimeField(auto_now_add=True)
ordered_date = models.DateTimeField()
ordered = models.BooleanField(default=False)
billing_address = models.ForeignKey('BillingAddress', on_delete=models.SET_NULL, blank=True, null=True)
payment = models.ForeignKey('Payment', on_delete=models.SET_NULL, blank=True, null=True)
def __str__(self):
return self.user.username
class BillingAddress(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
street_address = models.CharField(max_length=100)
apartment_address = models.CharField(max_length=100)
country = CountryField(multiple=False)
city = models.CharField(max_length=50)
state = models.CharField(max_length=50)
phone = models.CharField(max_length=50)
def __str__(self):
return self.user.username
def orders(request):
order = Order.objects.filter(user=request.user.id, ordered=True)
billing_address = BillingAddress.objects.filter(user=request.user.id)
context = {
'order': order,
'billing_address_item': order_billing_address,
}
return render(request, 'orders.html', context)
{% for address in billing_address %}
Country: {{ address.street_address|capfirst }}
{% endfor %}</p>
Instead of using a separate query for billing address, fetch it from the order instance:
def orders(request):
orders = Order.objects.filter(user=request.user.id, ordered=True)
context = {
'orders': orders,
}
return render(request, 'orders.html', context)
orders.html:
{% for order in orders %}
{{ order.billing_address.street_address }}
{{ order.billing_address.country }}
...
{% endfor %}

Finding the Cross-Section of two List views in one Django template

I have two models that feed one view.
models.py
class Item(models.Model):
item_name = models.CharField(max_length=100)
item_type = models.ForeignKey(Item_type, on_delete=models.SET_NULL, null=True)
owned_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)****
added_at = models.DateTimeField('date item added')
updated_at = models.DateTimeField('last update')
def __str__(self):
return self.item_name
class Item_status(models.Model):
item = models.ForeignKey(Item, on_delete=models.SET_NULL, null=True)
borrower = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
loaned_at = models.DateTimeField(default=None, blank=True, null=True)
due_back = models.DateTimeField(default=None, blank=True, null=True)
def __time__(self):
return self.loaned_at
def itemname(self):
return (self.item.item_name)
I have the following view
views.py
class LoanedItemsByUserListView(LoginRequiredMixin,generic.ListView):
model = Item_status
template_name ='catalog/item_status_list_borrowed_user.html'
paginate_by = 10
def get_queryset(self):
return Item_status.objects.filter(borrower=self.request.user).order_by('due_back')
def get_context_data(self, **kwargs):
context = super(LoanedItemsByUserListView, self).get_context_data(**kwargs)
context['Owned_list'] = Item.objects.filter(owned_by=self.request.user, item_type = 1)
context['Loaned_list'] = Item_status.objects.exclude(borrower=self.request.user).exclude(borrower__isnull=True)
return context
I would like to find the cross section of the 'Owned_list' and the 'Loaned_list' in a single template
Something like
<h2>Loaned Books</h2>
{% if Owned_list %}
<ul>
{% for thing in Owned_list.item_name and in Loned_list.item.item_name %}
<li>
{{thing}}
</li>
{% endfor %}
</ul
{% else %}
<p>There are no books in the library.</p>
{% endif %}
I have take a look at the django documentation here https://docs.djangoproject.com/en/1.11/topics/class-based-views/generic-display/, and around SO but not found exactly what I am looking for.
Thanks!

Categories