Search code examples
pythondjangoemail-templates

how do I render out all objects of a loop in a email template


I'm trying to render all the product names, prices and quantities related to list_ordered_items into my email template. But the email contains just one product object detail instead of multiple product object details, I'm already looping through in the view! what's causing this? how do I fix this?

models

class Product(models.Model):
    name = models.CharField()
    final_price =  models.DecimalField()

class OrderItem(models.Model):
    product = models.ForeignKey(Product)
    quantity = models.IntegerField(default=0)

views

list_ordered_items = OrderItem.objects.filter(order__customer__user=request.user).select_related('product')

for loi in list_ordered_items:
    product_name = loi.product.name
    product_price = loi.product.final_price
    product_qty = loi.quantity
    context = {'product_name': product_name, 'product_qty': product_qty, 'product_price': product_price}

email template

<tr>
    <td align="left" style="padding:0;Margin:0"><h4 style="Margin:0;line-height:17px;mso-line-height-rule:exactly;font-family:arial, 'helvetica neue', helvetica, sans-serif;font-size:14px"><strong></strong>{{product_name}}<strong></strong></h4></td>
</tr>
<tr>
    <td style="padding:0;Margin:0;text-align:center;font-size:13px;line-height:13px" width="15%" align="center"><p style="Margin:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;font-family:arial, 'helvetica neue', helvetica, sans-serif;line-height:21px;color:#333333;font-size:14px"><strong></strong>{{product_qty}}<strong></strong></p></td>
    <td style="padding:0;Margin:0;text-align:center;font-size:13px;line-height:13px" width="30%"><p style="Margin:0;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;mso-line-height-rule:exactly;font-family:arial, 'helvetica neue', helvetica, sans-serif;line-height:21px;color:#333333;font-size:14px"><strong></strong>${{product_price | floatformat:2}}<strong></strong></p></td>
</tr>

current view:

enter image description here

should look like this:

enter image description here


Solution

  • In views.py, your current code just renames the variables on each iteration without saving them anywhere. Instead, you should put the loop in your template. For example,

    in views.py:

    list_ordered_items = OrderItem.objects.filter(order__customer__user=request.user).select_related('product')
    
    context = {'list_ordered_items':list_ordered_items}

    in yourtemplate.html: (you can add your styling into the below code)

    {% for item in list_ordered_items %}
    <tr>
      <td>{{item.name}}</td>
    </tr>
    <tr>
      <td>{{item.price}}</td>
      <td>{{item.qty}}</td>
    </tr>
    {% endfor %}