Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Django – store.models.Customer.MultipleObjectsReturned: get() returned more than one Customer — it returned 2"

I am trying to make an e-commerce website where "AnonymousUser" or Guest user can order and check out products by providing their name, email, and address. But after clicking the "Make Payment" button, my terminal was having an error that says "store.models.Customer.MultipleObjectsReturned: get() returned more than one Customer — it returned 2!"

When I try to login and do the process for an authenticated user, it doesn’t have an error. It just happen to AnonymousUsers.

Here’s my checkout.html:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{% extends 'store/main.html' %}
{% load static %}
{% block content %}
     <div class="row">
        <div class="col-lg-6">
            <div class="box-element" id="form-wrapper">
                <form id="form">
                    <div id="user-info">
                        <div class="form-field">
                            <input required class="form-control" type="text" name="name" placeholder="Name..">
                        </div>
                        <div class="form-field">
                            <input required class="form-control" type="email" name="email" placeholder="Email..">
                        </div>
                    </div>
                    
                    <div id="shipping-info">
                        <hr>
                        <p>Shipping Information:</p>
                        <hr>
                        <div class="form-field">
                            <input class="form-control" type="text" name="address" placeholder="Address..">
                        </div>
                        <div class="form-field">
                            <input class="form-control" type="text" name="city" placeholder="City..">
                        </div>
                        <div class="form-field">
                            <input class="form-control" type="text" name="state" placeholder="State..">
                        </div>
                        <div class="form-field">
                            <input class="form-control" type="text" name="zip" placeholder="zip code..">
                        </div>
                    </div>

                    <hr>
                    <input id="form-button" class="btn btn-success btn-block" type="submit" value="Continue">
                </form>
            </div>

            <br>
            <div class="box-element hidden" id="payment-info">
                <small>Paypal Options</small>
                <button id="make-payment">Make Payment</button>
            </div>
            
        </div>

        <div class="col-lg-6">
            <div class="box-element">
                <a  class="btn btn-outline-dark" href="{% url 'cart' %}">&#x2190; Back to Cart</a>
                <hr>
                <h3>Order Summary</h3>
                <hr>
                {% for item in items %}
                    <div class="cart-row">
                        <div style="flex:2"><img class="row-image" src="{{item.product.imageURL}}"></div>
                        <div style="flex:2"><p>{{item.product.name}}</p></div>
                        <div style="flex:1"><p>₱{{item.product.price|floatformat:2}}</p></div>
                        <div style="flex:1"><p>x{{item.quantity}}</p></div>
                    </div>
                {% endfor %}
                <h5>Items:   {{order.get_cart_items}}</h5>
                <h5>Total:   ₱{{order.get_cart_total|floatformat:2}}</h5>
            </div>
        </div>
    </div>

<script type="text/javascript">
    var shipping = '{{order.shipping}}'
    var user = '{{request.user.is_authenticated}}'
    var total = '{{order.get_cart_total|floatformat:2}}'
    

    if(shipping == 'False'){
        document.getElementById('shipping-info').innerHTML = ''
    }

    if (user == "True"){
        document.getElementById('user-info').innerHTML = ''
    }

    if (shipping == 'False' && user == "True"){
        //Hide entire form if user is logged in and shipping is false
        document.getElementById('form-wrapper').classList.add('hidden');
        //Show payment if logged in user wants to buy an item that does not require shipping
        document.getElementById('payment-info').classList.remove('hidden');
    }

    var form = document.getElementById('form')
    
    form.addEventListener('submit', function(e){
        e.preventDefault()
        console.log('Form Submitted...')
        document.getElementById('form-button').classList.add("hidden");
        document.getElementById('payment-info').classList.remove("hidden");
    })

    document.getElementById('make-payment').addEventListener('click', function(e){
        submitFormData()
    })

    function submitFormData(){
        console.log('Payment button clicked')

        var userFormData = {
            'name':null,
            'email':null,
            'total':total,
        }

        var shippingInfo = {
            'address':null,
            'city':null,
            'state':null,
            'zip':null,
        }

        if (shipping != 'False'){
            shippingInfo.address = form.address.value
            shippingInfo.city = form.city.value
            shippingInfo.state = form.state.value
            shippingInfo.zip = form.zip.value
        }

        if (user == 'False'){
            userFormData.name = form.name.value
            userFormData.email = form.email.value
        }

        var url = '/process_order/'
        fetch(url,{
            method:'POST',
            headers:{
                'Content-Type':'application/json',
                'X-CSRFToken':csrftoken,
            },
            body:JSON.stringify({'form':userFormData, 'shipping':shippingInfo})
        })

        .then((response) => response.json())
        .then((data) => {
            console.log('Success:', data);
            alert('Transaction Completed');

            cart ={}
            document.cookie = 'cart=' + JSON.stringify(cart) + ";domain=;path=/"

            window.location.href = "{% url 'store' %}"
        })
         
    }

</script>

{% endblock content %}

Here’s my models.py:

from django.db import models
from django.contrib.auth.models import User

# Create your models here.

class Customer(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True)
    name = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200)

    def __str__(self):
        return self.name

class Product(models.Model):
    name = models.CharField(max_length=200)
    price = models.DecimalField(max_digits=9, decimal_places=2)
    digital = models.BooleanField(default=False, null=True, blank=True)
    image = models.ImageField(null=True, blank=True)

    def __str__(self):
        return self.name

    @property
    def imageURL(self):
        try:
            url = self.image.url 
        except:
            url = ''
        return url

class Order(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE, null=True, blank=True)
    date_ordered = models.DateTimeField(auto_now_add=True)
    complete = models.BooleanField(default=False)
    transaction_id = models.CharField(max_length=20, null=True)

    def __str__(self):
        return str(self.id)

    @property
    def shipping(self):
        shipping = False
        orderitems = self.orderitem_set.all()
        for i in orderitems:
            if i.product.digital == False:
                shipping = True
        return shipping

    @property
    def get_cart_total(self):
        orderitems = self.orderitem_set.all()
        total = sum([item.get_total for item in orderitems])
        return total

    @property
    def get_cart_items(self):
        orderitems = self.orderitem_set.all()
        total = sum([item.quantity for item in orderitems])
        return total

class OrderItem(models.Model):
    product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
    order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
    quantity = models.IntegerField(default=0, null=True, blank=True)
    date_added = models.DateTimeField(auto_now_add=True)

    @property
    def get_total(self):
        total = self.product.price * self.quantity
        return total

class ShippingAddress(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True)
    order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
    address = models.CharField(max_length=200, null=False)
    city = models.CharField(max_length=200, null=False)
    state = models.CharField(max_length=200, null=False)
    zip = models.CharField(max_length=200, null=False)
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.address

Here’s my views.py:

from django.http import JsonResponse
from django.shortcuts import render
from .models import *
import json
import datetime
from .utils import cookieCart, cartData, guestOrder

def store(request): 

    data = cartData(request)
    cartItems = data['cartItems']

    products = Product.objects.all()
    context = {'products':products, 'cartItems': cartItems}
    return render(request, 'store/store.html', context)

def cart(request):

    data = cartData(request)
    cartItems = data['cartItems']
    order = data['order']
    items = data['items']

    context = {'items':items, 'order':order, 'cartItems': cartItems}
    return render(request, 'store/cart.html', context)

def checkout(request):
    data = cartData(request)
    cartItems = data['cartItems']
    order = data['order']
    items = data['items']

    context = {'items':items, 'order':order, 'cartItems': cartItems}
    return render(request, 'store/checkout.html', context)

def updateItem(request):
    data = json.loads(request.body)
    productId = data['productId']
    action = data['action']
    print('Action:', action)
    print('Product:', productId)

    customer = request.user.customer
    product = Product.objects.get(id=productId)
    order, created = Order.objects.get_or_create(customer=customer, complete=False)

    orderItem, created = OrderItem.objects.get_or_create(order=order, product=product)

    if action == 'add':
        orderItem.quantity = (orderItem.quantity + 1)
    elif action == 'remove':
        orderItem.quantity = (orderItem.quantity - 1)

    orderItem.save()

    if orderItem.quantity <= 0:
        orderItem.delete()

    return JsonResponse('Item was added', safe=False)

def processOrder(request):
    transaction_id = datetime.datetime.now().timestamp()
    data = json.loads(request.body)

    if request.user.is_authenticated:
        customer = request.user.customer
        order, created = Order.objects.get_or_create(customer=customer, complete=False)

    else:
        customer, order = guestOrder(request, data)

    total = float(data['form']['total'])
    order.transaction_id = transaction_id

    if total == order.get_cart_total:
        order.complete = True
    order.save()

    if order.shipping == True:
        ShippingAddress.objects.create(
            customer=customer,
            order=order,
            address=data['shipping']['address'],
            city=data['shipping']['city'],
            state=data['shipping']['state'],
            zip=data['shipping']['zip'],
        )

    return JsonResponse('Payment complete!', safe=False)

And here’s my utils.py:

import json
from .models import *

def cookieCart(request):
    try:
        cart = json.loads(request.COOKIES['cart'])
    except:
        cart = {}
    
    print('Cart:', cart)
    items = []
    order = {'get_cart_total':0, 'get_cart_items':0, 'shipping': False}
    cartItems = order['get_cart_items']

    for i in cart:
        try:
            cartItems += cart[i]["quantity"]

            product = Product.objects.get(id=i)
            total = (product.price * cart[i]['quantity'])

            order['get_cart_total'] += total
            order['get_cart_items'] += cart[i]['quantity']

            item = {
                'product':{
                    'id':product.id,
                    'name':product.name,
                    'price':product.price,
                    'imageURL':product.imageURL,
                    },
                'quantity': cart[i]['quantity'],
                'get_total': total,
                }
            items.append(item)

            if product.digital == False:
                order['shipping'] = True

        except:
            pass
    return {'cartItems': cartItems, 'order': order, 'items': items}

def cartData(request):
    if request.user.is_authenticated:
        customer = request.user.customer
        order, created = Order.objects.get_or_create(customer=customer, complete=False)
        items = order.orderitem_set.all()
        cartItems = order.get_cart_items

    else:
        cookieData = cookieCart(request)
        cartItems = cookieData['cartItems']
        order = cookieData['order']
        items = cookieData['items']

    return {'cartItems': cartItems, 'order': order, 'items': items}

def guestOrder(request, data):
    print('User is not logged in...')

    print('COOKIES:', request.COOKIES)
    name = data['form']['name']
    email = data['form']['email']

    cookieData = cookieCart(request)
    items = cookieData['items'] 

    customer, created = Customer.objects.get_or_create(
        email=email,
        )
    customer.name = name
    customer.save()

    order = Order.objects.create(
        customer=customer,
        complete=False,
        )

    for item in items:
        product=Product.objects.get(id=item['product']['id'])

        orderItem = OrderItem.objects.create(
            product=product,
            order=order,
            quantity=item['quantity']
            )

    return customer, order

How can I get rid of that error and let guest users check out without the need to make an account or login?

>Solution :

Here you are creating Customer object for AnonymousUser (simply not logged User).

customer, created = Customer.objects.get_or_create(
        email=email,
        )

I think it might find more that one if you have same email used more than once with.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading