why my submit input isn't working in django?

Viewed 96

I have a form so an user can ask for a loan and it will tell them if it´s approved or not. The problem is not the logic, it´s the submit input that doesn't work. It will not save the form in the database or show me the errors because of the submit input. Maybe is something wrong with the succes_url? I don't know, but here's my code:

views.py:

#don't worry about the logic part of the form, it's just to show how it´s supposed to work




class LoanRequest(LoginRequiredMixin, generic.CreateView):
    form_class = LoanForm
    success_url = reverse_lazy('Prestamos')
    template_name = 'Prestamos/template/Prestamos/prestamos.html'

    def form_valid(self, form):
        user = self.request.user
        cliente = Cliente.objects.get(user_id = user.id)
        if not cliente.approve_loan(form.cleaned_data.get('loan_total')):
            form.add_error(field=None, error='loan not approved')
            return self.form_invalid(form)
        else:
            form.instance.customer_id = cliente
            super(LoanRequest, self).form_valid(form)
            return render(self.request, 'Prestamos/template/Prestamos/prestamos.html', context={'form': form, 'success_msg': 'loan approved!'})

urls.py:

urlpatterns = [
    path('prestamos/', views.LoanRequest.as_view(), name = 'prestamos'),
]

forms.py:

class LoanForm(forms.ModelForm):
    class Meta:
        model = Prestamo #loan in English
        fields = ['loan_type', 'loan_total', 'loan_date']

and the template:

<div class="container">
            {%if success_msg%}
                <p class="alert alert-success">{{success_msg}}</p>
            {%endif%}
            <form action="" method="POST">
                {%csrf_token%}
                {%for field in form%}
                    <div class="form-group">    
                        <label for="{{field.label}}">{{field.label}}</label>
                        {{field}}
                    </div>
                    {%for error in field.errors%}
                      <p>{{error}}</p>
                    {%endfor%}
                {%endfor%}
                <input type="submit" value="request"></input>
            </form>
        </div>

models.py:

class Prestamo(models.Model):
    loan_id = models.AutoField(primary_key=True)
    loan_type = models.CharField(max_length=20, 
    choices = [('PERSONAL', 'PERSONAL'), ('HIPOTECARIO', 'HIPOTECARIO'), ('PRENDARIO', 'PRENDARIO')])
    loan_date = models.DateField()
    loan_total = models.IntegerField()
    customer_id = models.IntegerField()

    class Meta:
        db_table = 'prestamo'
1 Answers

Well, <input> is an empty tag, it does not contain anything, so don't close it.

Additionally, I'd recommend you to make gaps between template tags, like it should be {% endfor %} not {%endfor%}.

Also, remove the empty action attribute from form, as Django always take current page route if not mentioned or empty string.

Also use novalidate on form for rendering custom errors.

Try this template:

<div class="container">
            {% if success_msg %}
                <p class="alert alert-success">{{success_msg}}</p>
            {% endif %}
            <form method="POST" novalidate>
                {% csrf_token %}
                {% for field in form %}
                    <div class="form-group">    
                        <label for="{{field.label}}">{{field.label}}</label>
                        {{field}}
                    </div>
                    {% for error in field.errors %}
                      <p>{{error}}</p>
                    {% endfor %}
                {% endfor %}
                <input type="submit" value="request">
            </form>
</div>

Edit:

One mistake I could see the name for the view is prestamos and you have mentioned it as Prestamos, which is wrong.

So:

class LoanRequest(LoginRequiredMixin, generic.CreateView):
    form_class = LoanForm
    success_url = reverse_lazy('prestamos')
    template_name = 'Prestamos/template/Prestamos/prestamos.html'
Related