【问题标题】:Django - QuerySet logic error "get() returned more than one..."Django - QuerySet 逻辑错误“get() 返回多个...”
【发布时间】:2014-03-25 11:51:24
【问题描述】:

目前正在使用 Tango with Django 书作为参考。我的数据库中有一堆产品,这些产品属于外键关系引用的类别。我似乎在返回产品视图时遇到了问题,该视图包含有关该特定产品的所有信息。

示例:数据库中有两台戴尔笔记本电脑、一台 iPhone 和两台 iPad。 iPhone 将返回产品信息,但对于 iPad 和戴尔笔记本电脑,它将返回消息 "get() returned more than one Product -- it returned 2!",这当然意味着它找到了两个具有相似匹配名称的产品。我尝试将name__icontains 中的name__icontains 更改为name__iexact,但随后它完全停止工作,我是否遗漏了一些非常明显的东西?就像我一样。

    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)

【问题讨论】:

    标签: django python-3.x django-views


    【解决方案1】:

    我尝试在 def product_view 中将 name_icontains 更改为 name_iexact,但随后它完全停止工作,我是否遗漏了一些非常明显的东西?

    这可能是因为您搜索的产品名称与存储的产品名称​​完全不匹配。

    如果您想进行近似/模糊搜索,您可以使用__icontains(),但只能使用一个搜索结果。

    示例代码:

    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
    

    【讨论】:

    • 啊,太棒了,它似乎工作,但说我有两个产品,分别名为 iPhone 5c 和 iPhone 5s,点击 5c 将带我到 5c 页面,但点击 5s 页面将带我到5c 页。我直接从shell运行了一些查询,例如Product.objects.filter(name__icontains="iphone 5c") Product.objects.filter(name__iexact="iphone 5c") Product.objects.filter(slug__iexact="iphone-5c")
    • 所有这些都返回 iPhone 5c,如果我只定义“iPhone”,它会返回所有这些。传递的 URL(我假设)是 iphone-5c,它应该分别返回 iPhone 5c 或 iPhone 5s,但如果我将查询指定为 slug__iexact 它不会返回任何内容。
    • @user2942863,如果您想完全匹配使用name__iexact,但请确保您查询的字符串与您正在搜索的字段完全匹配。
    • 感谢您的建议。这很奇怪,因为当我在终端中运行查询时,它们返回了正确的对象。结果是 URL 映射正则表达式中缺少连字符,因此连字符被忽略。不知道我是否应该对它这么简单感到惊讶,但是啊!学习到教训了。再次感谢。
    【解决方案2】:

    所以我假设您需要不止一种产品,因为您的查询有多个匹配项。 “获取”期望只抓取一个匹配的项目。如果您希望这两个项目都遍历它们,那么请删除 get 和 use 过滤器。这将返回一组可迭代的对象,您可以在模板或视图中解析。

    如果你有一个可迭代对象的列表;

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

    如果你有一个由 get 返回的对象;

    {{ object_variable_name.foreign_key_name.foreign_key_attribute }}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-02
      • 1970-01-01
      • 1970-01-01
      • 2014-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多