azeem_pdd
azeem_pdd

Reputation: 36

<order> object is not iterable

i am trying to fetch orders record from order model and passing as a context into template but in template problem occurs when i use a loop inside a loop such as

                                        {% for o in objects %}
                                        {% for p in o %}
                                        <tr>
                                            <td>{{forloop.counter}}</td>
                                            <td>{{p.img.url}}</td>
                                            <td>{{o.date}}</td>
                                            <td>{{p.price}}</td>
                                            {% if o.order_status == 'completed' %}
                                            <td><small style="background-color:green;"><span class="badge badge-success">{{o.order_status}}</span></small></td>                    
                                            {% else %}
                                            <td><small style="background-color:rgb(231, 211, 26);"><span class="badge badge-warning">{{o.order_status}}</span></small></td>
                                            {% endif %}
                                        </tr>
                                        {% endfor %}
                                        {% endfor %}

i am fetching products related to a particular order object and passing as a context with the as that particular order object such as

context=OrderProduct.fetch_customer_order_products(customer)

OrderProduct.py model

from django.db.models.deletion import DO_NOTHING
from django.shortcuts import get_object_or_404
from django.db.models import Case, When
from django.db import models
from django.db.models.fields.related import ForeignKey
from .order import Order
from .products import Products
from .customer import Customer

class OrderProduct(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    product = models.ForeignKey(Products, on_delete=models.DO_NOTHING)
    customer = models.ForeignKey(Customer, on_delete=DO_NOTHING, default="")
    quantity = models.IntegerField()

    def __str__(self):
        return self.product.name
    @staticmethod
    def fetch_customer_order_products(cust):
        obj = Order.objects.filter(customer=cust)
        dict = {}
        context={}
        for o in obj:
            l = []
            id = o.id
            prods = list(Order.objects.filter(id=id).values('products'))
            for a in range(0,len(prods)):
                l.append(prods[a]['products'])
            dict[o] = l
            prods = list(Products.objects.filter(id__in=l))  # to be passed as context 
            
         
            context[o]=prods
        context['objects'] = obj

        return context

order.py model

from django.db import models
from django.db.models.enums import Choices
from django.db.models.fields.related import ManyToManyField
from .customer import Customer
from .products import Products
from .payment_method import Payment_method
from datetime import datetime

Order_status_choices = (
    ('created', 'Created'),
    ('approved', 'Approved'),
    ('paid','Paid'),
    ('packaged','Packaged'),
    ('shipped','Shipped'),
    ('completed','Completed'),
)

class Order(models.Model):
    name = models.CharField(max_length=20, default="")
    products = models.ManyToManyField(Products)
    customer = models.ForeignKey(Customer, on_delete=models.DO_NOTHING)
    address = models.CharField(max_length=100, default='')
    order_status = models.CharField(max_length=20, choices = Order_status_choices, default='created')
    shipping_address = models.CharField(max_length=100, default='')
    phno = models.BigIntegerField(default=00000000000)
    email = models.EmailField(default="")
    date = models.DateTimeField(default=datetime.now,blank=True)
    price = models.IntegerField(default=0)
    payment_method = models.ForeignKey(Payment_method, on_delete=models.DO_NOTHING, null=True)
    name_additional = models.CharField(max_length=20, null=True,blank=True)
    phno_additional = models.BigIntegerField(null=True, blank=True)

    def __str__(self):
        return self.name

    @staticmethod
    def get_order_by_customer_id(customer):
        return Order.objects.filter(customer=customer)

myaccount.html file

{% extends 'base.html' %}
{% load static %}
{% load cart %}
{% block content %}
        
        <!-- Breadcrumb Start -->
        <div class="breadcrumb-wrap">
            <div class="container-fluid">
                <ul class="breadcrumb">
                    <li class="breadcrumb-item"><a href="#">Home</a></li>
                    <li class="breadcrumb-item"><a href="#">Products</a></li>
                    <li class="breadcrumb-item active">My Account</li>
                </ul>
            </div>
        </div>
        <!-- Breadcrumb End -->
        
        
        <!-- My Account Start -->
        <div class="my-account">
            <div class="container-fluid">
                <div class="row">
                    <div class="col-md-3">
                        <div class="nav flex-column nav-pills" role="tablist" aria-orientation="vertical">
                            <a class="nav-link active" id="dashboard-nav" data-toggle="pill" href="#dashboard-tab" role="tab"><i class="fa fa-tachometer-alt"></i>Dashboard</a>
                            <a class="nav-link" id="orders-nav" data-toggle="pill" href="#orders-tab" role="tab"><i class="fa fa-shopping-bag"></i>Orders</a>
                            <a class="nav-link" id="payment-nav" data-toggle="pill" href="#payment-tab" role="tab"><i class="fa fa-credit-card"></i>Payment Method</a>
                            <a class="nav-link" id="address-nav" data-toggle="pill" href="#address-tab" role="tab"><i class="fa fa-map-marker-alt"></i>address</a>
                            <a class="nav-link" id="account-nav" data-toggle="pill" href="#account-tab" role="tab"><i class="fa fa-user"></i>Account Details</a>
                            <a class="nav-link" href="index.html"><i class="fa fa-sign-out-alt"></i>Logout</a>
                        </div>
                    </div>
                    <div class="col-md-9">
                        <div class="tab-content">
                            <div class="tab-pane fade show active" id="dashboard-tab" role="tabpanel" aria-labelledby="dashboard-nav">
                                <h4>Dashboard</h4>
                                <p>
                                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. In condimentum quam ac mi viverra dictum. In efficitur ipsum diam, at dignissim lorem tempor in. Vivamus tempor hendrerit finibus. Nulla tristique viverra nisl, sit amet bibendum ante suscipit non. Praesent in faucibus tellus, sed gravida lacus. Vivamus eu diam eros. Aliquam et sapien eget arcu rhoncus scelerisque.
                                </p> 
                            </div>
                            <div class="tab-pane fade" id="orders-tab" role="tabpanel" aria-labelledby="orders-nav">
                                <div class="table-responsive">
                                    <table class="table table-bordered">
                                        <thead class="thead-dark">
                                            <tr>
                                                <th>Sno</th>
                                                <th>image</th>
                                                <th>DateTime</th>
                                                <th>price</th>
                                                <th>Order Status</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            {% for o in objects %}
                                            {% for p in o %}
                                            <tr>
                                                <td>{{forloop.counter}}</td>
                                                <td>{{p.img.url}}</td>
                                                <td>{{o.date}}</td>
                                                <td>{{p.price}}</td>
                                                {% if order.order_status == 'completed' %}
                                                <td><small style="background-color:green;"><span class="badge badge-success">{{order.order_status}}</span></small></td>                    
                                                {% else %}
                                                <td><small style="background-color:rgb(231, 211, 26);"><span class="badge badge-warning">{{order.order_status}}</span></small></td>
                                                {% endif %}
                                            </tr>
                                            {% endfor %}
                                            {% endfor %}
                                        </tbody>
                                    </table>
                                </div>
                            </div>
                            <div class="tab-pane fade" id="payment-tab" role="tabpanel" aria-labelledby="payment-nav">
                                <h4>Payment Method</h4>
                                <p>
                                    Lorem ipsum dolor sit amet, consectetur adipiscing elit. In condimentum quam ac mi viverra dictum. In efficitur ipsum diam, at dignissim lorem tempor in. Vivamus tempor hendrerit finibus. Nulla tristique viverra nisl, sit amet bibendum ante suscipit non. Praesent in faucibus tellus, sed gravida lacus. Vivamus eu diam eros. Aliquam et sapien eget arcu rhoncus scelerisque.
                                </p> 
                            </div>
                            <div class="tab-pane fade" id="address-tab" role="tabpanel" aria-labelledby="address-nav">
                                <h4>Address</h4>
                                <div class="row">
                                    <div class="col-md-6">
                                        <h5>Payment Address</h5>
                                        <p>123 Payment Street, Los Angeles, CA</p>
                                        <p>Mobile: 012-345-6789</p>
                                        <button class="btn">Edit Address</button>
                                    </div>
                                    <div class="col-md-6">
                                        <h5>Shipping Address</h5>
                                        <p>123 Shipping Street, Los Angeles, CA</p>
                                        <p>Mobile: 012-345-6789</p>
                                        <button class="btn">Edit Address</button>
                                    </div>
                                </div>
                            </div>
                            <div class="tab-pane fade" id="account-tab" role="tabpanel" aria-labelledby="account-nav">
                                <h4>Account Details</h4>
                                <div class="row">
                                    
                                    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
                                    <div id="profile-container">
                                    {% if profile.img %}
                                    <img width="50" height="70" id="profileImage" src="{{profile.img.url}}" />
                                    {% else %}
                                    <img width="50" height="70" id="profileImage" src="https://p1.pxfuel.com/preview/423/292/62/girl-studio-female-woman-profile-black-and-white.jpg" />
                                    {% endif %}
                                    </div><br><br><br><br><br><br>
                                    <form action="/my-account" method="post" enctype="multipart/form-data">
                                        {% csrf_token %}
                                        
                                            {{form.as_p}}
                                        {% if request.session.customer|check_customer_profile %}
                                        <div class="col-md-12">
                                            <button type="submit" class="btn">update profile</button>
                                            <br><br>
                                        </div>
                                        {% else %}
                                        <div class="col-md-12">
                                            <button type="submit" class="btn">Create profile</button>
                                            <br><br>
                                        </div>
                                        {% endif %}
                                    </form>
                                    
                                </div>
                                
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <!-- My Account End -->
        
       {% endblock %}

myaccount.py

from django.utils.decorators import method_decorator
from ..middlewares.authorization import auth_middleware
from store.models.customer import Customer
from django.views import View
from django.shortcuts import render,redirect
from ..models.order import Order
from ..models.orderproduct import OrderProduct
from ..models.profile import Profile
from ..forms.ProfileForm import ProfileForm
class MyAccount(View):
    @method_decorator(auth_middleware)
    def get(self, request):
        customer = request.session.get('customer')
        

        if customer:
            profile = Profile.whether_customer_exists(customer)
            form = None
            form = ProfileForm(instance=profile)
            context=OrderProduct.fetch_customer_order_products(customer)
            
            context['form']=form
            
            if profile:
                context['profile'] = profile
        
        print(context)  
        return render(request, 'my-account.html',context)

    def post(self, request):
        customer = request.session.get('customer')
        if customer:
            profile = Profile.whether_customer_exists(customer)
            if profile:
                form = ProfileForm(request.POST or None, request.FILES or None,instance=profile)
                if form.is_valid():
                    form.save()
                
            else:
                cust = Customer.objects.filter(id = customer).first()
                
                
                
                form = ProfileForm(request.POST or None, request.FILES or None)
                form1 = form.save(commit=False)
                form1.customer = cust
                form1.save()
                
            
            form = ProfileForm(instance=profile)
            context = {'form':form}

            return render(request, 'my-account.html',context)
                

                
            
        else:
            return redirect('login')

Upvotes: 0

Views: 187

Answers (1)

azeem_pdd
azeem_pdd

Reputation: 36

actually what i was trying to do is to fetch products ordered by a customer related to a particular Ordermodel object and their repective quantity from OrderProductmodel i was giving the order object to inner loop to show products related to that object as

                                {% for o in objects %}
                                {% for p in o %}
                                <tr>
                                    <td>{{forloop.counter}}</td>
                                    <td>{{p.img.url}}</td>
                                    <td>{{o.date}}</td>
                                    <td>{{p.price}}</td>
                                    {% if o.order_status == 'completed' %}
                                    <td><small style="background-color:green;"><span class="badge badge-success">{{o.order_status}}</span></small></td>                    
                                    {% else %}
                                    <td><small style="background-color:rgb(231, 211, 26);"><span class="badge badge-warning">{{o.order_status}}</span></small></td>
                                    {% endif %}
                                </tr>
                                {% endfor %}
                                {% endfor %}

so how is solved the problem was to fetch order query set object to template via context and inside template used a loop to iterate over queryset and get order object and then created a custom template filter inside templatetags folder to fetch the products related to a particular object by giving order object as argument to the cutstom filter such as

{%for o in objects %}
                                <h4>Order{{forloop.counter}}</h4>
                                <div class="table-responsive">
                                    <table class="table table-bordered">
                                        <thead class="thead-dark">
                                            <tr>
                                                <th>Sno</th>                                   
                                                <th>image</th>
                                                <th>Name</th>
                                                <th>price</th>
                                                <th>Quantity</th>
                                                <th>product total</th>
                                                <th>DateTime</th>
                                                <th>Order Status</th>
                                            </tr>
                                        </thead>
                                        <tbody>
                                            
                                            {% for p in o|get_object_related_products:request.session.customer %}
                                            <tr>
                                                <td>{{forloop.counter}}</td>
                                                <td>
                                                <div class="img">
                                                    <a href="#"><img src="{{p.img.url}}" alt="Image" height="50px" width="50px"></a>
                                                </div>
                                                </td>
                                                <td>{{p.name}}</td>
                                                <td>{{p.price}}</td>
                                                <td>{{o|get_product_quantity:p}}</td>
                                                <td>{{o|get_order_total:p}}</td>
                                                <td>{{o.date}}</td>
                                                {% if o.order_status == 'completed' %}
                                                <td><small style="background-color:green;"><span class="badge badge-success">{{o.order_status}}</span></small></td>                    
                                                {% else %}
                                                <td><small style="background-color:rgb(231, 211, 26);"><span class="badge badge-warning">{{o.order_status}}</span></small></td>
                                                {% endif %}
                                            </tr>
    {% endfor %}

so thanks to anyone who made consideratiions...

Upvotes: 1

Related Questions