Django - Пагинация не работает для последней страницы

На моем сайте я хочу показать вина с пагинацией, 9 страниц на странице (предположим, у нас 22 вина). Вина хранятся в интерфейсе администратора, каждое вино имеет такие поля, как название, тип, описание и ImageField для загрузки соответствующих изображений. Однако, когда я нажимаю на третью (последнюю) страницу, появляется следующая страница:


Ошибка значения в /page-name/ Атрибут 'image' не имеет связанного с ним файла. Метод запроса: GET URL запроса: http://localhost/page-name/?page=3 Версия Django: 5.0.4 Тип исключения: ValueError Значение исключения:
Атрибут 'image' не имеет связанного с ним файла. Местоположение исключения: [путь].venv\Lib\site-packages\django\db\models\fields\files.py, строка 41, in _require_file Поднято во время: [app-name].views.wines_page_red


В консоли я получаю следующее предупреждение: TypeError: 'ImageFieldFile' object is not subscriptable

...и куча исключений. Я новичок в Django и не понимаю, что может вызвать проблему, так как все изображения для соответствующих товаров загружены. Где-то читал, что метод, который я использовал для пагинации, может быть нестабильным, поэтому я попытался упорядочить вина по их названию, и теперь 2-я страница выдает ту же ошибку. Вот вид, url-часть и шаблон:

Вид:

def wines_page_red(request):
    red_wines_list = Wine.objects.filter(type='Red')
    paginator = Paginator(red_wines_list, 9)

    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    return render(request, 'red-wines.html', {'page_obj': page_obj})

Часть url на уровне проекта:

urlpatterns = [

    path('admin/', admin.site.urls),
    path('', include('[app-name].urls')),

] + static(django.conf.settings.MEDIA_URL, document_root=django.conf.settings.MEDIA_ROOT)

Часть настроек:

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# URL that handles the media served from MEDIA_ROOT, used for managing stored files.

MEDIA_URL = '/media/'

MEDIA_ROOT = BASE_DIR / ''

Шаблон:

   <section class="products section-padding">
        <div class="container">
            <div class="row">
                {% for wine in page_obj %}
                <div class="col-lg-4 col-12 mb-3">
                    <div class="product-thumb">
                        <a href="product-detail.html">
                            <img src="{{ MEDIA_URL }}{{ wine.image.url }}" class="img-fluid product-image" alt="">
                        </a>

                        <div class="product-info d-flex">
                            <div>
                                <h5 class="product-title mb-0">
                                    <a href="product-detail.html" class="product-title-link">{{ wine.name }}</a>
                                </h5>

                            <p class="product-p">{{ wine.description }}</p>
                        </div>
                    </div>
                </div>
            </div>
            {% endfor %}
        </div>
    </div>
</section>

<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>

        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">next</a>
            <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
</div>

Это не имеет никакого отношения к пагинации. Это просто означает, что есть Wine объект, в котором изображение не ссылается на (существующий) файл изображения.

Сначала вы можете проверить, не является ли изображение None:

{% if wine.image %}
  <a href="product-detail.html">
    <img src="{{ wine.image.url }}" class="img-fluid product-image" alt="image of the wine">
  </a>
{% endif %}

Кроме того, вы должны убедиться, что содержимое ссылается на реальный файл, иначе мы получим 404 при обслуживании медиафайла.

Обычно MEDIA_ROOT в шаблоне не нужен: .url обычно сам добавляет медиа-префикс, если он настроен правильно.

Вы также можете отфильтровать Wine без изображения:

def wines_page_red(request):
    red_wines_list = Wine.objects.filter(type='Red', image__isnull=False)
    paginator = Paginator(red_wines_list, 9)
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(request, 'red-wines.html', {'page_obj': page_obj})
Вернуться на верх