Django - QuerySet logic error “get() returned more than one…”

Question!

Currently using the Tango with Django book for reference. I have a bunch of products in my database in categories which are referenced with Foreign Key relationships. I seem to have an issue with returning the product view, which houses all the information about that particular product.

Example: There are two Dell laptops, one iPhone, and two iPads in the database. The product information will be returned for the iPhone, but for the iPads and the Dell laptops, it will return the message "get() returned more than one Product -- it returned 2!" which of course means that it's found two products with similar matching names. I've tried changing the name__icontains to name__iexact in the def product_view but then it stops working completely, am I missing something very obvious? As it feels like I am.

    url(r'^products/(?P<category_name_url>\w+)/$', views.category_view, name='category_view'),
    url(r'^products/(?P<category_name_url>\w+)/(?P<product_name_url>\w+)', views.product_view, name='product_view')

def category_view(request, category_name_url):
    context = RequestContext(request)

    category_list = Category.objects.order_by('name')
    category_name = category_name_url.replace('_', ' ')
    context_dict = {'category_name': category_name,
                    'categories': category_list}

    try:
        category = Category.objects.get(name__iexact=category_name)
        product = Product.objects.filter(category=category)

        context_dict['product'] = product
        context_dict['category'] = category

    except Category.DoesNotExist:
        pass

    return render_to_response('category_view.html', context_dict, context)

def product_view(request, category_name_url, product_name_url):
    context = RequestContext(request)

    category_list = Category.objects.order_by('name')
    category_name = category_name_url.replace('_', ' ')
    product_name = product_name_url.replace('-', ' ')
    context_dict = {'category_name': category_name,
                    'product_name': product_name,
                    'categories': category_list}

    try:
        category = Category.objects.get(name__iexact=category_name)
        product = Product.objects.get(name__icontains=product_name)
        context_dict['category'] = category
        context_dict['product'] = product

    except Product.DoesNotExist:
        pass

    return render_to_response('product_view.html', context_dict, context)


Answers

So I'm assuming you want more than one product as you have more than one match with your query. "Get" expects to only grab one matching item. If you want both items to iterate through them, than drop the get and use filter. this will return an iterable set of objects you can parse through in your template or view.

if you have a list of iterable objects;

{% for i in product_match_list %}
{{ i.foreign_key_name.foreign_key_attribute }}
{% endfor %}

if you have one object returned by get;

{{ object_variable_name.foreign_key_name.foreign_key_attribute }}


This video can help you solving your question :)
By: admin