@DarkiDeuce

Почему значения из БД не передаётся в HTML файл?

Сегодня скачал свой же проект с гитхаба (возможно проблема в этом, но я почти уверен, что нет), начал работу на другом компьютере. Столкнулся с проблемой.

На сайте реализована следующая логика: пользователь открывает страницу на который размещён конструктор для сборки ПК, с подбором комплектующих. Подбор производиться следующим образом: при нажатии на кнопку "выбрать" рядом с соответствующим компонентом компьютера (материнская плата, видеокарта и т.д.), пользователь попадает на страницу, где на выбор представлены все комплектующие в данной категории и их характеристики, а так же размещены кнопки рядом с каждым компонентом, после нажатия кнопки пользователь попадает на предшествующую страницу, где на месте кнопки "выбрать" расположена фотография компонента и его характеристики. При нажатии на кнопку для выбора конкретного компонента производиться POST запрос и передаётся id компонента в функцию в файле views.py, там id сохраняется в сессию, а после по id производиться обращение к БД и достаются все необходимые значения для html файла, в котором есть условие, согласно которому если переданная переменная пуста, то будут отображены теги по умолчанию, а если переменная имеет значения, то будут выведены фотография и характеристики компонента.

Однако именно это условие не срабатывает, всегда выводятся значения по умолчанию, будто передаваемое значение пустое. Не могу разобраться почему так происходит.

Больше всего меня сбивает с толку тот факт, что именно этот код работал полностью корректно до скачивания проекта с Git'a.

views.py
def constructor(request):
    if request.method == 'POST':
        motherboard_id = request.POST.get('motherboard_id')

        if motherboard_id is not None:
            session = SessionStore(request.session.session_key)
            session['motherboard_id'] = motherboard_id
            session.save()

    session = SessionStore(request.session.session_key)
    motherboard_id = session.get('motherboard_id')

    motherboard = Motherboard.objects.filter(id=motherboard_id)

    return render(request, 'constructor/constructor.html', context={'motherboard': motherboard,
                                                                    }
                  )


html код страницы с конструктором:
{% extends "base.html" %}

{% load static %}

{% block content %}
    <div class="main">
        <h1>Конструктор системного блока</h1>
        <div class="constructor">
            <div class="component">
                {% if motherboard %}
                    <div class="photo-component">
                        <img src="{% static 'img/motherboard/'|add:motherboard.0.name|add:'.png' %}" alt="{{ motherboard.0.name }}">
                    </div>
                    <div class="description">
                        <h3>Материнская плата: {{ motherboard.0.name }}</h3>
                        <p><strong>Сокет:</strong> {{motherboard.0.socket_motherboard }}</p>
                        <p><strong>Тип опреративной памяти:</strong> {{motherboard.0.memory_type }}</p>
                        <a href="{% url 'motherboard_selection' %}" class="add-component-btn">Заменить</a>
                    </div>
                {% else %}
                    <div class="photo-component">
                        <img src="{% static 'img/primordial/motherboard.png' %}" alt="motherboard">
                    </div>
                    <div class="description">
                        <h3>Материнская плата</h3>
                        <p>Материнская плата (MB) – основа компьютера. На плату как конструктор собираются остальные комплектующие. Материнская плата не отвечает за быстродействие компьютера, но за функционал, от нее зависит количество нужных выходов и разъемов, поддержка режимов SLI, Cross-Fire, Raid, и конечно разводка системы питания.</p>
                        <a href="{% url 'motherboard_selection' %}" class="add-component-btn">Добавить компонент</a>
                    </div>
                {% endif %}
            </div>

            <div class="line"></div>
        </div>
    </div>
{% endblock %}


html код страницы, на которой отображены элементы
{% extends "base.html" %}

{% load static %}

{% block content %}
    <div class="main">
        <h1>Конструктор системного блока</h1>
        <div class="constructor">
            {% if motherboard_list %}
                {% for motherboard in motherboard_list %}
                    <div class="component">
                        <div class="photo-component">
                            <img src="{% static 'img/motherboard/'|add:motherboard.name|add:'.png' %}" alt="{{ motherboard.name }}">
                        </div>
                        <div class="description">
                            <h3>Материнская плата: {{ motherboard.name }}</h3>
                            <div class="description">
                                <p><strong>Сокет:</strong> {{motherboard.socket_motherboard }}</p>
                                <p><strong>Тип опреративной памяти:</strong> {{motherboard.memory_type }}</p>
                                {{ motherboard.id }}
                                <form method="POST" action="{% url 'constructor' %}">
                                    {% csrf_token %}
                                    <input type="hidden" name="motherboard_id" value="{{ motherboard.id }}">
                                    <button type="submit" class="add-component-btn">Выбрать</button>
                                </form>
                            </div>
                        </div>
                    </div>
                    <div class="line"></div>
                {% endfor %}
            {% endif %}
        </div>
    </div>

{% endblock %}
  • Вопрос задан
  • 51 просмотр
Решения вопроса 1
@DarkiDeuce Автор вопроса
Вопрос решён!

Дело в том, что при каждом вызове функции создавался новый экземпляр класса сессии. Из-за чего сохранённые в ней значения становились недоступны. Для решения это проблемы необходимо создать экземпляр класса в функции лишь один раз. Значения из сессии можно будет достать только в рамках одного запроса. Чтобы значения были доступны на протяжении нескольких запросов необходимо описать дополнительный класс SessionPerRequestMiddleware.

Для этого в папке приложения нужно создать файл middlewares.py. В этом файле нужно описать класс:
from django.contrib.sessions.backends.db import SessionStore

class SessionPerRequestMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # Создаем экземпляр класса сессии и сохраняем его в атрибуте request.session
        session = SessionStore(request.session.session_key)
        request.session = session

        response = self.get_response(request)

        # Сохраняем изменения в сессии
        session.save()

        return response


Далее надо указать этот класс в настройках проекта
MIDDLEWARE = [
    'PC_Components.middlewares.SessionPerRequestMiddleware'
]


После этого можно обращаться к значениям сессии в рамках множества запросов.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы