Отправка формы обратно и из двух представлений в 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. :)

Вернуться на верх