Отправка формы обратно и из двух представлений в Django
Я делаю проект, который предполагает, что пользователи могут писать в форме и затем сохранять ее в виде файла с уценкой. Мне нужно найти способ показать пользователю, как будет выглядеть уценка, которую он сейчас пишет, после разбора; это будет показано на отдельной статической странице с кнопкой возврата, чтобы вернуться к написанию.
Последняя часть вызывает у меня проблемы, поскольку мне удалось показать пользователю, как будет выглядеть его файл, но я не смог найти способ вернуть его в исходную форму ввода, откуда он был взят
Предварительный просмотр HTML
{% extends "encyclopedia/layout.html" %}
{% block title %}
Encyclopedia
{% endblock %}
{% block body %}
<h1>Preview</h1>
<h3>{{title}}</h3>
<hr>
{{preview|safe}}
<form action="{% url 'new_entry' %}" method="POST">
{% csrf_token %}
<input type="submit" name="return" value="Return">
</form>
{% endblock %}
Новая запись HTML
{% block title %}
Encyclopedia
{% endblock %}
{% block body %}
<h1>New Entry</h1>
<div class="form-group">
<form action="{% url 'new_entry' %} " method="POST">
{{form.as_table}}
{% csrf_token %}
<input type="submit" value="Save" name="submit">
<input type="submit" value="Preview" name="preview">
</form>
</div>
{% endblock %}
Виды для предварительного просмотра и нового HTML
def preview(request):
#Retrieve data from the request
form = EntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data['title']
body = form.cleaned_data['body']
# Nonfunctioning part
#It's supposed to return the request to the original function
#and letting it know that it has to pre-populate the form
if 'return' in request.POST:
return new_entry(request, fill_form=True)
#Render the contents of the form
return render(request, "encyclopedia/entry_preview.html",
{"title":title,"preview":body})
def new_entry(request, fill_form = False):
#Non functioning part
#Supposedly should get the request that the view 'preview'
#recieved and get the form from there
form = EntryForm()
if fill_form is True:
form = EntryForm(request.POST)
if form.is_valid():
title = form.cleaned_data['title']
body = form.cleaned_data['body']
#If form returned submit then save the file
if 'submit' in request.POST:
util.save_entry(title,body)
return redirect(reverse('new_entry'))
#If form returned preview then call function to display
#users input rendered correctly
elif 'preview' in request.POST:
#Pass the POST request to this other function
return preview(request)
#Else just render an empty form
else:
return render(request,'encyclopedia/new_entry.html',
{'form':form})
Форма основана на Модели, она содержит только два основных поля, title
и body
.
В любом случае, я открыт для других идей, чтобы справиться с этим, моя проблема в том, что когда вызывается функция preview
, она отображает переданные значения, но теперь переданные параметры исчезли, и я не могу вернуться к представлению new_entry
.
Также я думал о передаче данных через URL, но тело может быть длиной в тысячи слов
В продолжение комментариев, я кратко объясню один из способов решения этой проблемы. Для этой задачи я бы использовал очень маленькую библиотеку django под названием django_htmx. Просто взгляните на использование htmx и менее чем через десять минут вы будете готовы реализовать это с легкостью. Ваша форма будет выглядеть примерно так:
<form action="{% url 'new_entry' %}"
data-hx-post="{% url 'new_entry' %}"
data-hx-target="#your-container-id"
data-hx-swap="innerHTML"
method="POST">
{{form.as_table}}
{% csrf_token %}
<input type="submit" value="Save" name="submit">
<input type="submit" value="Preview" name="
</form>
data-hx-post
задает url для размещения этой формы через ajax. А data-hx-target
задает контейнер, в который будет вставлен ответ от ajax-запроса. data-hx-swap
указывает htmx вставить ответ в этот контейнер.
Поместите ваш шаблон encyclopedia/entry_preview.html
в блок include. И включите его в ту же страницу, что и форму. Не забудьте присвоить элементу контейнера идентификатор, чтобы вы могли указать на него в htmx с помощью data-hx-target
.
В вашей функции view вы можете сказать:
def new_entry(request, fill_form = False):
if request.method == "POST":
if request.htmx:
# The request is made with htmx ajax call...
# So we render only one side of the page. The display side.
return render(request, "encyclopedia/entry_preview.html",
{"title":title,"preview":body})
else:
#render the page normally here. both with form and with preview container.
Попробуйте и спросите, если вы застряли. У вас будет хорошая динамическая страница редактирования разметки.
PS: Вы можете использовать data-hx-trigger
, чтобы он обновлялся даже во время набора текста. точно как Stackoverflow. :)