Сохранение и отображение входов формы Django при отправке POST

--ПРОБЛЕМА--

Я создал базовый калькулятор, используя Django. Приложение принимает некоторые основные вводы формы перед выполнением некоторых вычислений и возвращает результаты пользователю, однако я хочу, чтобы вводы пользователя оставались видимыми в форме при отправке. В настоящее время происходит следующее.

  1. Пользователь вводит значения в форму и отправляет с помощью кнопки "Рассчитать".

enter image description here

  1. Результаты возвращаются, как ожидалось, но форма и значения больше не присутствуют.

enter image description here

  1. Пользователь может нажать кнопку "Рассчитать", чтобы вернуться к началу процесса и пустой форме.

- ЖЕЛАЕМЫЙ РЕЗУЛЬТАТ-

enter image description here

--КОД--

forms.py

from django import forms

class InvestmentForm(forms.Form):
    starting_amount = forms.FloatField()
    number_of_years = forms.FloatField()
    return_rate = forms.FloatField()
    annual_additional_contribution = forms.FloatField()

views.py

from django.shortcuts import render
from django.views import View
from .forms import InvestmentForm


class Index(View):
    def get(self, request):
        form = InvestmentForm()
        return render(request, 'loancalculator/index.html', {'form': form})

    def post(self, request):
        form = InvestmentForm(request.POST)

        if form.is_valid():


                total_result = form.cleaned_data['starting_amount']
                total_interest = 0
                yearly_results = {}

                for i in range(1, int(form.cleaned_data['number_of_years'] +1)):
                    yearly_results[i] = {}

                    # CALCULATE THE INTEREST 
                    interest = total_result * (form.cleaned_data['return_rate'] / 100)
                    total_result += interest 
                    total_interest += interest

                    # ADDITIONAL CONTRIBUTION 
                    total_result += form.cleaned_data['annual_additional_contribution']

                    # SET YEARLY RESULTS 
                    yearly_results[i]['interest']  = round(total_interest, 2)
                    yearly_results[i]['total'] = round(total_result,2)


                    # CREATE CONTEXT 
                    context = {
                        'total_result': round(total_result,2),
                        'yearly_results': yearly_results,
                        'number_of_years': int(form.cleaned_data['number_of_years'])
                    }
            
                # RENDER THE TEMPLATE

                return render(request, 'loancalculator/index.html', context)


        
        else:
            form = InvestmentForm()
            return render(request, 'loancalculator/index.html', {'form':form})
        
            
        

index.html

{% extends 'loancalculator/base.html' %}
{% load crispy_forms_tags %}

{% block content %} 


<div class="row justify-content-center">
    
    <div class="col-4 border bg-light">
    <div class="row t-5">
        <div class="col-12 col-md-6 mx-md-auto">
            <h1> Investment Calculator</h1>
                <h5> Enter the details below to see your estimate</h5>

            <form action="" method="POST">
                {% csrf_token %}
                {{ form|crispy }}
                <button class="btn btn-primary" type="submit">Calculate</button>                
            </form>
            <br>
        </div>
    </div>
    </div>

    <div class="col-4 border">
        <div class="row t-5">
            <div class="col-12 col-md-6 mx-md-auto">
                <h1>Investment Results</h1>
                <h3> After {{ number_of_years }} years, your investment is worth ${{ total_result }}</h3>
    
                <div class="mt-5">
                    <table class="table">
                        <thead>
                            <tr>
                                <th scope="col">Year</th>
                                <th scope="col">Interest</th>
                                <th scope="col">Total</th>
                            </tr>
                        </thead>
                        <tbody>
    
                            {% for key, value in yearly_results.items %}
    
                            <tr>
                                <th scope="row">{{ key }}</th>
                                <td>{{ value.interest }}</td>
                                <td>{{ value.total }}</td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
      </div>
    </div>  
  </div>

{% endblock content %}

При создании контекста значение 'form' не устанавливается (views.py, в разделе get())

Два способа, которыми вы можете добиться желаемого, как я это вижу:

Метод 1
. Используйте sessions для хранения данных, а затем перенаправьте их в форму, используя initial значения формы. Это, вероятно, самый простой вариант, поскольку он наиболее точно соответствует тому, что у вас уже есть.

from django.shortcuts import render
from django.views import View
from .forms import InvestmentForm


class Index(View):
    def get(self, request):

        # Fill in the initial values on the unbound form:
        initial = {
            'starting_amount': request.session.get('starting_amount'),
            'number_of_years': request.session.get('number_of_years'),
            'return_rate': request.session.get('return_rate'),
            'annual_additional_contribution': request.session.get('annual_additional_contribution'),
        }

        form = InvestmentForm(initial=intial)
        return render(request, 'loancalculator/index.html', {'form': form})

    def post(self, request):
        form = InvestmentForm(request.POST)

        if form.is_valid():

                # After getting the cleaned_data, set a session variable to hold it
                total_result = form.cleaned_data['starting_amount']
                request.session['starting_amount'] = total_result

                number_of_years = int(form.cleaned_data['number_of_years']
                request.session['number_of_years'] = number_of_years

                return_rate = form.cleaned_data['return_rate']
                request.session['return_rate'] = return_rate

                annual_additional_contribution = form.cleaned_data['annual_additional_contribution']
                request.session['annual_additional_contribution'] = annual_additional_contribution
                
                total_interest = 0
                yearly_results = {}

                for i in range(1, number_of_years +1)):
                    yearly_results[i] = {}

                    # CALCULATE THE INTEREST 
                    interest = total_result * (return_rate / 100)
                    total_result += interest 
                    total_interest += interest

                    # ADDITIONAL CONTRIBUTION 
                    total_result += annual_additional_contribution

                    # SET YEARLY RESULTS 
                    yearly_results[i]['interest']  = round(total_interest, 2)
                    yearly_results[i]['total'] = round(total_result,2)

                    # CREATE CONTEXT 
                    context = {
                        'total_result': round(total_result,2),
                        'yearly_results': yearly_results,
                        'number_of_years': number_of_years)
                    }
            
                # RENDER THE TEMPLATE

                return render(request, 'loancalculator/index.html', context)
                
        
        else:
            form = InvestmentForm()
            return render(request, 'loancalculator/index.html', {'form':form})

Метод 2
. Из того, что вы показываете здесь, в любом случае, вы могли бы просто использовать JavaScript для выполнения вычислений, захватывая значения непосредственно из DOM после их ввода, выполняя вычисления на передней стороне с помощью JavaScript, а затем заполняя значения, указывая места, где вы хотите, чтобы результаты отображались в DOM. Нет необходимости в формах, нет перезагрузки страниц.

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