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)
Was it helpful?

Solution

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?

That might be because product name that you searched does not exactly match with the one stored.

If you want to do approximation/fuzzy search you can use __icontains(), but use only one search result.

Sample code:

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

    except IndexError:
        #product does not exists
        pass

OTHER TIPS

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 }}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top