Передача аргументов представлениям Django с отображаемой страницы
Мне было поручено создать веб-интерфейс для существующей базы данных MySQL. Я новичок в веб-разработке в целом, решил использовать Django, потому что я довольно продвинутый пользователь Python. Однако я полностью застрял на выполнении того, что, казалось бы, должно быть довольно обычной задачей.
База данных содержит информацию о спецификациях программного обеспечения (SBOMs) и связанных с ними компонентах программного обеспечения. Прямо сейчас все, что я хочу сделать, это попросить пользователя выбрать SBOM из базы данных, получить программное обеспечение, связанное с этим SBOM, и отобразить результаты. Я бы хотел, чтобы пользователь мог просматривать результаты на странице.
Я пытаюсь сделать это, отображая список SBOM в системе в формате HTML, с каждой записью, имеющей соответствующую кнопку, которая будет передавать выбранные параметры следующему представлению в строке. Насколько я могу судить, у меня все настроено так
Вот как настроен мой urls.py:
urlpatterns = [
path("", views.select_bill, name="select_bill"),
path("select_software/<int:bill_num>", views.select_software, name="select_software"),
path("select_software/<int:bill_num>/<int:page>", views.select_software, name="select_software")
]
мой views.py:
from django.shortcuts import render
from django.core.paginator import Paginator
from frontend.models import SoftwareResults
RESULTS_PER_PAGE = 25
def select_bill(request):
bills = get_bills() # Function that queries the existing MySQL database and gets a list of SBOMs
return render(request, "frontend/select_bill.html", {"bills": bills})
def select_software(request, bill_num, page=1):
<snip>
И frontend/select_bill.html:
<table>
{% for entry in bills %}
{% url 'select_software' "{{ entry.Row }}" 1 as entry_select %}
<tr><td>
<a href="{{ entry_select }}">Submit</a></td><td>{{ entry.Filename }}</td></tr>
</table>
Насколько я могу судить, это должно привести к созданию ссылки на форму /select_software/<bill_num>/1, которая, в свою очередь, должна привести к моему представлению select_software через urls.py. Проблема в том, что URL-адрес преобразуется в обратную ссылку на страницу select_bills, по-видимому, полностью игнорируя приведенный выше макрос {% url %}.
Что я пробовал:
- Ввод макроса
{% url %}непосредственно в текстhref. Это приводит к ошибке при отображении страницы - Используя форму, а не ссылку. Когда я попытался использовать метод POST, я получил те же результаты. С помощью метода GET я мог бы закодировать свои параметры в URL, но это не сработало, когда я захотел, чтобы некоторые страницы перенаправлялись друг на друга.
Я в полном недоумении. Как я могу заставить Django создать нужный мне URL?
Ввод макроса
{% url %}непосредственно в текст внешней ссылки. Это приводит к ошибке при отображении страницы
Это всего лишь догадки, потому что вы не указали ошибку, которую Джанго услужливо сделал для вас. :) Но:
Вероятно, не следует присваивать нескольким маршрутам одинаковые названия. Используйте, например, name="select_software_with_default_page" для первого select_software, чтобы его можно было отличить от второго. Как бы то ни было, Django на самом деле не может знать, какой маршрут генерировать.
Также обратите внимание на эту часть документации:
Этот синтаксис
{% url ... as var %}не приведет к ошибке, если представление отсутствует. На практике вы будете использовать его для создания ссылок на необязательные представления:
Итак, что, вероятно, произошло (хотя я не проверял), так это то, что url завершается безрезультатно, entry_select остается пустым, сгенерированный HTML-код имеет вид <a href="" ...>, и какой браузер будет ссылаться на тот же URL-адрес это отображается на дисплее.
Вместо этого вы можете использовать более привычную форму:
<a href="{% url 'select_software' "{{ entry.Row }}" 1 %}">Submit</a></td><td>{{ entry.Filename }}</td></tr>
который, как вы заметили, выдает ошибку, когда что-то не так:
Обратите внимание, что если изменяемый URL-адрес не существует, вы получите сообщение об исключении
NoReverseMatch, которое приведет к отображению страницы с ошибкой на вашем сайте.
Ошибки - это хорошо: они подсказывают, что нужно исправить.
Естественно, я нашел ответ на этот вопрос вскоре после публикации в StackOverflow. Оказалось, что это синтаксическая ошибка при форматировании моих шаблонов. Вот что в итоге сработало:
{% for entry in bills %}
<tr><td>
<form action="{% url 'select_software' bill_num=entry.Row page=1"><button type="submit">Select</button></form></td> [...]</tr>
{% endfor %}