Home > Enterprise >  MultipleObjectsReturned at /sport/1/ get() returned more than one Product -- it returned 3
MultipleObjectsReturned at /sport/1/ get() returned more than one Product -- it returned 3

Time:03-12

I am sorting products by categories. When I am viewing product's details, the program outputs following error:

MultipleObjectsReturned at /default/1/ get() returned more than one Product -- it returned 2! Users/artemiikhristich/PycharmProjects/Eshop-original/store/views.py, line 114, in product_detail product = get_object_or_404(Product, slug=slug)

product.html

This template is used for viewing product details

% extends "store/main.html" %}



{% block content %}
{% load static %}


<link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Tutorial</title>
    <!-- Fonts -->
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
    <!-- CSS -->
    <link href="static/css/style.css" rel="stylesheet">
    <meta name="robots" content="noindex,follow" />

  </head>

  <body>
    <main >

      <!-- Left Column / Headphones Image -->



      <!-- Right Column -->
      <div >

        <!-- Product Description -->
        <div >
          <span></span>
            <h1>{{product.name}}</h1>
                  <div >
        <img data-image="black" src="{{ product.imageURL }}">


      </div>
            <p>"{{product.description}}"</p>
        </div>


        <!-- Product Configuration -->

        </div>

        <!-- Product Pricing -->
        <div >
            <button data-product="{{product.id}}" data-action="add" >Add to Cart</button>

            <div >
              <a href="#">How to take the measurements</a>
            </div>
        </div>
      </div>
    </main>

    <!-- Scripts -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js" charset="utf-8"></script>
    <script src="static/js/script.js" charset="utf-8"></script>
  </body>
</html>

{% endblock %}

views.py

Here I have views for product_detail and category_detail

class ProductList(ListView):
    model = Product


def product_detail(request, category_slug, slug):
    product = get_object_or_404(Product, slug=slug)

    context = {
        'product': product
    }
    return render(request, 'store/product.html', context)

def category_detail(request, slug):
    category = get_object_or_404(Category, slug=slug)
    products = category.products.all()

    context = {
        'category': category,
        'products': products
    }

    return render(request, 'store/category_detail.html', context)
    enter code here

urls.py

from django.urls import path

from . import views
from .views import product_detail, category_detail

urlpatterns = [
    # Leave as empty string for base url
    path('', views.store, name="store"),
    path('cart/', views.cart, name="cart"),
    path('checkout/', views.checkout, name="checkout"),

    path('update_item/', views.updateItem, name="update_item"),
    path('process_order/', views.processOrder, name="process_order"),


    path('<slug:category_slug>/<slug:slug>/', product_detail, name='product-detail'),
    path('<slug:slug>/', category_detail, name='category_detail')

]

models.py

Here I am linking category and product with foreign key

class Category(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255, default=1)

    class Meta:
        verbose_name_plural = 'Categories'

    def __str__(self):
        return self.title


class Product(models.Model):
    category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE, default=1)
    name = models.CharField(max_length=200)
    price = models.FloatField()
    digital = models.BooleanField(default=False, null=True, blank=True)
    image = models.ImageField(null=True, blank=True)
    description = models.TextField(null=True, blank=True)
    slug = models.SlugField(max_length=255, default=1)



    def __str__(self):
        return self.name

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

Reference

CodePudding user response:

Well your challenge comes from you using get_object_or_404 it would be better to do something like this for your detail view:

def product_detail(request, category_slug, slug):
    product = Product.objects.get(slug=slug)

    context = {
        'product': product
    }
    return render(request, 'store/product.html', context)

CodePudding user response:

The issue was with the slug field. Previously, in models.py I had:

slug = models.SlugField(max_length=255, default=1)

I have slug field for Product and Category models. Slug is like a unique ID for the product. Previously I said that every time the product is created, the default=1. However, This was not unique as you can imagine. My solution:

slug = models.SlugField(max_length=255, unique=True, default=uuid.uuid1)

I am using unique=True with Universal Unique Identifier library

I hope this helps. Feel free to leave any comments

  • Related