Использование .first для ограничения набора запросов django приводит к тому, что TypeError в / path / object типа 'Product' не имеет len () - PullRequest
0 голосов
/ 24 декабря 2018

У меня есть строки в базе данных, где некоторые поля повторяются, например:

Collection name | Product ID | Product Name | Image URL
--------------------------------------------------------
Dusk            |001         | Chair        |/images/001.jpg
Dusk            |002         | Desk         |/images/001.jpg
Dusk            |003         | Table        |/images/001-t.jpg
Rome            |004         | Chair        |/images/002.jpg
Rome            |005         | Desk         |/images/002-d.jpg
Rome            |006         | Table        |/images/002-t.jpg
Noel            |007         | Chair        |/images/003.jpg
Noel            |008         | Desk         |/images/003.jpg
Noel            |009         | Stool        |/images/003.jpg

Может быть несколько строк, имеющих одно и то же имя коллекции, и некоторые другие поля также могут совпадать, например:URL-адрес изображения.

То, что я пытаюсь сделать, это вернуть все строки, где имя коллекции отличается, но только первую строку каждой из них.

Я пытаюсь сделать этов представлении django, используя '.first ()', но выдает ошибку, что у моего объекта модели нет длины.Я знаю, что записи возвращаются, так что это не проблема, но я не уверен, в чем может быть проблема.

Вот код, который я использую в моих views.py:

def bedroom_view(request):
    template = loader.get_template('/myapp/test_site/main_page/templates/main_page/bedroom.html')
    products = xroduct.objects.filter(product_category='Beds').first()
    page = request.GET.get('page', 1)
    paginator = Paginator(products, 9)
    try:
        prods = paginator.page(page)
    except PageNotAnInteger:
        prods = paginator.page(1)
    except EmptyPage:
        prods = paginator.page(paginator.num_pages)
    context={'prods': prods}    
    return HttpResponse(template.render(context))

1 Ответ

0 голосов
/ 25 декабря 2018

Проблема в том, что .first() [Django-doc] - это способ получения первого элемента набора запросов (или None, если такого элемента нет), а не первый элемент на"группу".

Примечание : вышеописанное не будет работать для большинство бэкэнды.На момент написания он работал только для PostgreSQL , хотя, конечно, это может измениться в будущем.Пожалуйста, обратитесь к документации по .distinct(), чтобы узнать, какие бэкэнды поддерживаются.

На PostgreSQL , вы можете использовать .distinct(*fields) [Django-doc] функция для получения строк, отличающихся одним или несколькими полями.

Так что здесь вы можете использовать:

def bedroom_view(request):
    template = loader.get_template('/myapp/test_site/main_page/templates/main_page/bedroom.html')
    products = Product.objects.filter(
        product_category='Beds'
    )<b>.distinct(
        'product_collection'
    )</b>
    page = request.GET.get('page', 1)
    paginator = Paginator(products, 9)
    try:
        prods = paginator.page(page)
    except PageNotAnInteger:
        prods = paginator.page(1)
    except EmptyPage:
        prods = paginator.page(paginator.num_pages)
    context={'prods': prods}    
    return HttpResponse(template.render(context))

product_collection может быть чем-то другим (имя поля, содержащего название коллекции).

...