代码之家  ›  专栏  ›  技术社区  ›  Samir Tendulkar

在Django中使用ForLoops在同一模板中显示ListView和DetailView

  •  0
  • Samir Tendulkar  · 技术社区  · 7 年前

    我想在“订单历史记录”页面(ListView)中添加一些订单详细信息(DetailView),请参阅下面的图像示例(我已经在Photoshop上制作了该图像)。我可以得到灰色部分(订单列表显示),但我不能得到项目详细信息显示在这个页面正确。如果单击查看订单详情,它将转到详情页,我可以在其中显示所有这些信息。但我也需要在列表页上有一个小摘要。见下面的例子。 如何更改视图或模板以实现此目的?查看下面的视图和模板

    下面是我需要我的订单历史页面的样子

    enter image description here

    下面是我的 我的模特.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
    

    灰色的订单详细信息正确,但订单项与订单不对应。应该像上面的第一张图片一样 enter image description here

    views.py第二次尝试错误: 我想会的 OrderItem.objects.all()) 在views.py和模板中的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
    

    同样,这是不正确的,这两个项目不属于订单。请参阅第一张图片了解应该如何处理。包含订单详情的灰色部分仍然正确

    enter image description here

    2 回复  |  直到 7 年前
        1
  •  1
  •   Diego Vinícius    7 年前

    这有点让人困惑,但我想我总算明白了…

    问题出在这里……由于django不是普通的,他们会在处理完所有的内容后将您的数据发送到模板…你在这里所做的是超越你的每一个价值 context['order_items'] 所以他们只将最后的数据发送到模板。

    for order in order_details:
        context['order_items'] = OrderItem.objects.filter(order=order)
    

    当您将更改为 context['order_items'] = OrderItem.objects.all() 如果没有ForLoop,现在您将获得所有订单项,而不设置任何订单…因此,当您尝试从第一个订单显示医嘱项目时,它们将显示所有医嘱项目。

    解决方法是使用 模板 这样你就可以在HTML处理的时候过滤你的数据了…

    因此,您需要根据订单筛选订单项…因为在您的页面中,您将显示许多订单,并且必须基于此订单筛选订单项

    在应用程序中创建一个名为templateTags的文件夹,创建一个文件作为templateTag(不要忘记创建 __init__.py 文件也)在这种情况下,我们将调用 order_templatetags.py

    应用程序/模板标签/订单模板标签.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/

        2
  •  0
  •   Samir Tendulkar    7 年前

    我终于明白了

    型号.py (在订单字段中添加相关的名称)

    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
    

    最后在templates.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 %}