我想在“订单历史记录”页面(ListView)中添加一些“订单详细信息”(DetailView),请参见下面的图像示例(我已经在photoshop中制作了图像)。我能够得到灰色部分(要显示的订单列表),但是我无法使项目详细信息正确显示在此页面中。如果单击查看订单详细信息,它将转到详细信息页面,在此可以显示所有这些信息。但我在ListPage中也需要一个小的摘要。请参见下面的示例。 如何更改视图或模板以实现此目的?在下面查看我的视图和模板
下面是我需要我的订单历史记录页面的样子
下面是我的我的模型。py
class Order(models.Model):
token = models.CharField(max_length=250, blank=True)
total = models.DecimalField(max_digits=6, decimal_places=2, verbose_name='USD Order Total')
emailAddress = models.EmailField(max_length=100, blank=True, verbose_name='Email Address')
created = models.DateTimeField(auto_now_add=True)
billingName = models.CharField(max_length=350, blank=True)
billingAddress1 = models.CharField(max_length=350, blank=True)
billingCity = models.CharField(max_length=100, blank=True)
billingZipcode = models.CharField(max_length=10, blank=True)
billingCountry = models.CharField(max_length=50, blank=True)
class OrderItem(models.Model):
product = models.CharField(max_length=250)
quantity = models.IntegerField()
price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='USD Price')
order = models.ForeignKey(Order, on_delete=models.CASCADE)
image = models.ImageField()
下面是我的模板
{% block body %}
<div>
<div class="text-center">
<br/>
<h1 class="text-center my_title">Order Purchase History</h1>
<br/>
{% if order_details %}
{% for order in order_details %}
<div class="row order_detail_div" >
<div class="col-md-2">
<b>Order Number: 1234{{ order.id }}</b><br/>
<small><em>Order Date: {{ order.created|date:"M d Y" }}</em></small>
</div>
<div class="col-md-1"></div>
<div class="col-md-3 text-left">
<b>Status: Paid</b><br/>
<b>Total items in Order: ()</b>
</div>
<div class="col-md-1"></div>
<div class="col-md-3 order_total_text">
<b>Order Total: ${{ order.total }}</b>
</div>
<div class="col-md-2 view_order_details">
<b><a href="{% url 'order:order_detail' order.id %}">View Order Details</a></b>
</div>
</div>
{% for item in order_items %} <!-- This gets the order items from the Order -->
<div class="row order_item_detail_div">
<div class="col-md-2">
<img src="{{ item.image }}" >
</div>
<div class="col-md-2">
{{ item.product}}
</div>
<div class="col-md-2">
{{ item.id}}
</div>
<div class="col-md-2">
{{ item.quantity}}
</div>
<div class="col-md-2">
{{ item.price}}
</div>
</div>
{% endfor %}
<br/>
{% endfor %}
{% else %}
<p>
You do not have any orders yet.<br/><br/>
<a href="{% url 'home' %}" class="btn btn-secondary">Add more recipes</a>
</p>
{% endif %}
</div>
</div>
<br/>
<br/>
{% endblock %}
Views.py第一次尝试 错误:出于某种原因,终端中的打印语句正确显示,但在浏览器中显示。 查看代码下方的图片
class OrderHistory(LoginRequiredMixin, ListView):
model = Order
template_name = 'order/order_list.html'
def get_context_data(self, **kwargs):
context = super(OrderHistory, self).get_context_data()
context['order_details'] = Order.objects.filter(emailAddress=self.request.user.email) #The code is correct till here
order_details = Order.objects.filter(emailAddress=self.request.user.email)
for order in order_details:
print("Order items are", OrderItem.objects.filter(order=order))
context['order_items'] = OrderItem.objects.filter(order=order)
return context
灰色的订单详细信息正确,但是OrderItems与订单不对应。应该像第一张图片一样(上图)
Views.py第二次尝试错误::我认为将在views.py中执行OrderItem.objects.all())
,模板中的forloop将修复该视图,但以下是我得到的错误>
class OrderHistory(LoginRequiredMixin, ListView):
model = Order
template_name = 'order/order_list.html'
def get_context_data(self, **kwargs):
context = super(OrderHistory, self).get_context_data()
context['order_details'] = Order.objects.filter(emailAddress=self.request.user.email) #The code is correct till here
print("Order items are", OrderItem.objects.all())
context['order_items'] = OrderItem.objects.all()
return context
同样,这是不正确的,这两个项目不属于Order。请参阅第一张图片。包含订单详细信息的灰色部分仍然正确
答案 0 :(得分:1)
这有点令人困惑,但我想我设法得到了要点...
问题出在这里...由于Django不是动态的,因此他们会在将所有内容处理到模板后将您的数据发送给您...您在这里所做的事情是覆盖context['order_items']
上的每个值,因此它们将发送给仅将最后一个数据作为模板。
for order in order_details:
context['order_items'] = OrderItem.objects.filter(order=order)
当您在不使用forloop的情况下更改为context['order_items'] = OrderItem.objects.all()
时,现在将获得所有Order Item而未设置任何订单...因此,当您尝试从第一个Order显示OrderItem时,它们将显示所有OrderItem。
解决方案使用 TEMPLATETAGS ,这样您就可以在处理HTML时过滤数据...
因此,您需要根据订单过滤您的OrderItem ...,因为在您的页面中,您将显示很多订单,并且您必须根据此订单过滤OrderItem。
在应用内创建一个名为templatetags的文件夹,并创建一个文件作为您的templatetag(也不要忘记创建__init__.py
文件),在这种情况下,我们将调用order_templatetags.py
app / templatetags / order_templatetags.py
from django import template
from .models import OrderItem
register = template.Library()
@register.filter
def filter_order_items(self):
return OrderItem.objects.filter(order__id=self.id)
在您的HTML中
<!-- IN TOP OF YOUR HTML (After Extends if you have it) PLACE THIS CODE -->
{% load order_templatetags %}
<!-- REST OF YOUR HTML CODE -->
{% for order in order_details %}
<!-- REST OF YOUR HTML CODE -->
{% for item in order|filter_order_items %} <!-- This gets the order items from the Order -->
<!-- YOUR HTML STUFFS -->
{% endfor %}
{% endfor %}
我的代码段:https://github.com/Diegow3b/django-utils-snippet/blob/master/template_tag.MD
Django文档:https://docs.djangoproject.com/en/2.0/howto/custom-template-tags/
答案 1 :(得分:0)
我终于弄清楚了
models.py (在订单字段中添加related_name)
class OrderItem(models.Model):
product = models.CharField(max_length=250)
quantity = models.IntegerField()
price = models.DecimalField(max_digits=5, decimal_places=2, verbose_name='USD Price')
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name="order_cushions")
image = models.ImageField()
views.py是
class OrderHistory(LoginRequiredMixin, ListView):
model = Order
template_name = 'order/order_list.html'
def get_context_data(self, **kwargs):
context = super(OrderHistory, self).get_context_data()
context['order_details'] = Order.objects.filter(emailAddress=self.request.user.email)
print("Order items are", OrderItem.objects.all())
context['order_items'] = OrderItem.objects.all()
return context
,最后进入template.py
{% for order in order_details %}
{% for item in order.order_cushions.all %} #this is the models related_name
{{item.image}} #this will get your image
{{item.product}}
{{item.price}}
{{item.quantity}} #decorate using bootstrap the way you like
{% endfor %}
{% endfor %}
答案 2 :(得分:0)
我的方法是使用Order内部的方法返回查询集
models.py
class Order(models.Model):
...
def items(self):
return OrderItem.objects.filter(order=self)
在循环中调用项目
Orderlist.html
{% for order in order_details %}
{% for item in order.items %}
<!-- YOUR HTML STUFFS -->
{% endfor %}
{% endfor %}