Автоматическая отправка формы django без создания бесконечного цикла

У меня есть проблема в моем приложении, которую я не могу решить наилучшим способом. Я изучаю Django и практически не имею опыта работы с Javascript, поэтому любая помощь будет оценена по достоинству. Возможно, это недостаток дизайна, поэтому я открыт для других идей.

Проблема Когда пользователь впервые попадает на страницу своей приборной панели, ему необходимо выбрать курс валюты на форме, в которой он хочет просматривать свои данные, например, USD, AUD, GBP и т.д. После того, как они отправят свой курс валюты, их приборная панель станет активной и доступной для просмотра. Я бы хотел, чтобы этот выбор оставался представленным при обновлении/загрузке или автоматически отправлялся при обновлении/загрузке. Таким образом, эта валюта останется, если пользователь не введет другую валюту.

Смотрите изображения до/после для контекста (игнорируйте значения, так как они неточны):

До/после того, как пользователь вводит валюту

Attempted solution I have tried using Javascript to auto submit on load which causes and infinite loop. I have read to use action to redirect to another page but i need it to stay on the same page. Unless this can be configured to only submit once after refresh/load I don't think this will work

<script type="text/javascript">
  $(document).ready(function() {
    window.document.forms['currency_choice'].submit();
  });
</script>

<div class="container">
    <div>
        <span>
    <h1>My Dashboard</h1>
        </span>
        <span>
        <form method="post" name="currency_choice">
            {% csrf_token %}
            {{ form_c.as_p }}
            <button class="btn btn-outline-success btn-sm">Submit</button>
        </form>
        </span>
    </div>
</div>

ФОРМА

class CurrencyForm(forms.ModelForm):
    currency = forms.ChoiceField(choices=currencies, label='Choose Currency:',)

    class Meta:
        model = UserCurrency
        fields = (
            'currency',
        )

МОДЕЛЬ

class UserCurrency(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    currency = models.CharField(max_length=10)

Вид

class MyDashboardView(TemplateView):
    template_name = 'coinprices/my-dashboard.html'

    def get(self, request, **kwargs):

        form_c = CurrencyForm(prefix='form_c')

        return render(request, self.template_name, {
            'form_c': form_c,
        })

    def post(self, request):

        currency = None

        form_c = CurrencyForm(request.POST, prefix='form_c')

        if request.method == 'POST':
            if form_c.is_valid():
                cur = UserCurrency.objects.filter(user_id=request.user.id)
                cur.delete()
                post = form_c.save(commit=False)
                post.user = request.user  # Registers the entry by the current user
                post.save()
                currency = UserCurrency.objects.filter(user_id=request.user.id).values('currency')
                currency = currency[0]['currency']
        else:
            form_c = CurrencyForm()

        rates = {'USD': 1.0, 'AUD': 1.321, 'GBP': 0.764, 'CAD': 1.249}

        deposit = 10000 / rates[currency]

        context = {
            'currency': currency,
            'deposit': dep,
            'form_c': form_c,
        }

        return render(request, 'coinprices/my-dashboard.html', context)

сделайте новый временный шаблон только с этим содержимым, сделайте представление для рендеринга и добавьте вызов представления в urls.py

{% csrf_token %}
{{ form_c.as_p }}

обновите текущий шаблон и вставьте ajax (я предполагаю, что вы имеете представление о jquery ajax)

<form method="post" name="currency_choice">
    <div id="currency-choice">
        {% csrf_token %}
        {{ form_c.as_p }}
    </div>
    <button class="btn btn-outline-success btn-sm">Submit</button>
</form>

<script>
    $.ajax({
       url : '{% url 'url-of-new-template' %}', 
       success : function(response){ 
           $('#currency-choice').html(response)
       },
    });
</script>

Обычной практикой для такого типа ситуаций является расчет и отображение информации о депозите в методе представления get. Если форма отправлена, метод post проверяет и сохраняет отправку, а затем автоматически перезагружает страницу.

Javascript не требуется, поэтому вы можете удалить его из вашего шаблона.

Я модифицировал вашу модель UserCurrency, чтобы использовать отношения OneToOneField с User. Это означает, что на каждую запись User может приходиться не более одной такой записи. Это также означает, что вы можете получить доступ к сохраненной валюте непосредственно из экземпляра пользователя.

Я также установил валюту по умолчанию "USD".

В представлении блоки try/except создают временный экземпляр UserCurrency, если он еще не существует.

МОДЕЛЬ

class UserCurrency(models.Model):
    user = models.OneToOneField(
        User,
        primary_key=True,
        related_name="user_currency",
        on_delete=models.CASCADE)
    currency = models.CharField(max_length=10, default="USD")

VIEW

from django.http import HttpResponseRedirect

class MyDashboardView(TemplateView):
    template_name = 'coinprices/my-dashboard.html'

    def get(self, request, **kwargs):
        """
        Get the saved currency, calculate the deposit, and display.

        """
        try:
            user_currency = request.user.user_currency
        except UserCurrency.DoesNotExist:
            user_currency = UserCurrency(user=request.user)
        
        rates = {'USD': 1.0, 'AUD': 1.321, 'GBP': 0.764, 'CAD': 1.249}
        deposit = 10000 / rates[user_currency.currency]
        form_c = CurrencyForm(instance=user_currency, prefix='form_c')

        return render(request, self.template_name, {
            'currency': user_currency.currency,
            'deposit': deposit,
            'form_c': form_c,
        })

    def post(self, request):
        """
        Validate the posted data, save/update the model instance,
        and reload the page. 

        """
        try:
            user_currency = request.user.user_currency
        except UserCurrency.DoesNotExist:
            user_currency = UserCurrency(user=request.user)
        
        form_c = CurrencyForm(request.POST, instance=user_currency, prefix='form_c')
        
        if form_c.is_valid():
            post.save()
            return HttpResponseRedirect(request.path_info)
Вернуться на верх