Django form fields as template variables - django

The main question is if it is possible to specifify specific form fields at different given locations in your html template in any smooth way. e.g. {{ form.password }} However, that does not seem to work. (I swear that I have seen this somewhere, but I just can't find it anymore on the internet)
My view for signing up new users is inheriting from UserCreationForm and looks kind of like this:
views.py
def signup(request):
if request.method == "POST":
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password)
login(request, user)
return redirect('home')
else:
form = UserCreationForm()
return render(request, 'core/authentication/registration_form.html', {'form': form})
It sends this form straight to the template registration_form.html, this is how I wish it worked:
<form class="form" method="POST" action="">
<div class="card-body">
<div class="input-group form-group-no-border">
<span class="input-group-addon">
<i class="now-ui-icons users_circle-08"></i>
</span>
{{ form.first_name }}
</div>
</div>
This is how it actually works (for now):
<form class="form" method="POST" action="">
<div class="card-body">
<div class="input-group form-group-no-border">
<span class="input-group-addon">
<i class="now-ui-icons users_circle-08"></i>
</span>
<input type="text" class="form-control" placeholder="First Name...">
</div>
</div>
This might be a stupid question, but oh well I am curious.
Thank you in advance

If i've understood your question correctly, here is how django says you should render django form fields manually.
{{ form.non_field_errors }} # here django renders errors which do not belong to any field
<div>
{{ form.field_1.errors }} # here django renders errors which belong to field_1
{{ form.field_1.label_tag }} # label element
{{ form.field_1 }} # input element
</div>
# some html
<div>
{{ form.field_2.errors }}
{{ form.field_2.label_tag }}
{{ form.field_2}}
</div>
You can read this here in the lower half.
Each field ( each label, input, error elements ) can be rendered with custom classes and widgets.

Related

Django Forms Invalid but no Errors

Maybe it might be an oversight but I do not know the point where I am getting it wrong.
My form is rendered correctly but it keeps failing without errors.
forms.py
from crispy_forms.helper import FormHelper
from django import forms
from django.utils.translation import ugettext as _
class BeneficiaryForm(forms.Form):
"""Add Beneficiary template form"""
# Form fields
account_currency = forms.ModelChoiceField(queryset=Currency.objects.all(), empty_label=_('Select account currency'))
bank_account_type = forms.CharField(max_length=50, required=False)
email = forms.CharField(max_length=150, required=False, help_text=_("We'll notify them when a transfer is made"))
name = forms.CharField(max_length=50, required=False)
swift_code = forms.CharField(max_length=11, required=False,
widget=forms.TextInput(attrs={'placeholder': 'MSBCCNBJ001'}))
iban = forms.CharField(max_length=34)
def __init__(self, *args, **kwargs):
super(BeneficiaryForm, self).__init__()
self.helper = FormHelper()
self.helper.form_show_labels = False
views.py
def beneficiaries(request):
"""View function for viewing Beneficiaries and adding a Beneficiary instance"""
if request.method == 'POST':
form = BeneficiaryForm(request.POST)
if form.is_valid():
print("Form is valid")
print(request.POST['bank_account_type'])
print(request.POST['email'])
print(request.POST['name'])
print(request.POST['iban'])
print(request.POST['swift_code'])
print("Form is invalid")
print(form.errors)
form = BeneficiaryForm()
context = {
'form': form
}
return render(request, 'dashboard/beneficiaries.html', context)
and in my rendered form. I have this block to show errors and nothing shows up
HTML
<form action="{% url 'beneficiary_index' %}" method="post">
{% csrf_token %}
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
{% if field != '__all__' %}
<strong>{{ field.label }}:</strong>
{% endif %}
{{ error|escape}}
</div>
{% endfor %}
{% endfor %}
{% endif %}
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">{% trans "Account currency" %}</label>'
</div>
{{ form.account_currency | as_crispy_field }}
</div>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">{% trans "Bank Account type" %}</label>
</div>
{{ form.bank_account_type | as_crispy_field }}
</div>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">Their email(optional)</label>
</div>
{{ form.email | as_crispy_field }}
</div>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">Full name of account holder</label>
</div>
{{ form.name | as_crispy_field }}
</div>
<h6>{% trans "Recipient Bank Information" %}</h6>
<hr>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">Swift code</label>
</div>
{{ form.swift_code | as_crispy_field }}
</div>
<div class="form-group">
<div class="form-label-group">
<label class="form-label" for="default-01">IBAN</label>
</div>
{{ form.iban | as_crispy_field }}
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">{% trans 'Add Beneficiary' %}</button>
</div>
</form>
This is the Html to the form. I have just tried all the suggestions and still without the errors.
Form is Invalid is the only thing printed on screen without the form.errors
You need to create the GET request empty form in the else block or return the request in the POST block.
You are re-creating an empty form before returning the response.
def beneficiaries(request):
"""View function for viewing Beneficiaries and adding a Beneficiary instance"""
if request.method == 'POST':
form = BeneficiaryForm(request.POST)
if form.is_valid():
print("Form is valid")
print(request.POST['bank_account_type'])
print(request.POST['email'])
print(request.POST['name'])
print(request.POST['iban'])
print(request.POST['swift_code'])
# do other stuff like saving to DB
# then redirect
else:
print("Form is invalid")
print(form.errors)
elif request.method == 'GET':
form = BeneficiaryForm()
else:
# maybe return 404
pass
context = {
'form': form
}
return render(request, 'dashboard/beneficiaries.html', context)
Or maybe you can try Class Based Views, to avoid the if-else block for GET and POST requests.
Try adding this to the place you want the error to appear (In the HTML file)
Better if you use it inside the tags.
{% if form.errors %}
<p>Form is invalid</p>
{% endif %}
I Hope this answers the question.

I don't understand why my form is not validating in django

I am still new to django. Playing around with a leadmanager app and I don't know why my form is not validating.
views
def index(request):
lead=LeadForm()
if request.method == 'POST':
lead=LeadForm(request.POST)
if lead.is_valid():
messages.success(request, f'Thank you for registering. Someone will be contacting you soon.')
return redirect('index')
else:
lead=LeadForm()
messages.error(request, f'Something went wrong. Please try again later.')
return render(request, "frontend/index.html", {'lead':lead})
in index.html
<form action="" method="POST" class="lead-form">
{% csrf_token %}
<fieldset class="lead-info">
<div class="form-control">
<label for="">Full Name</label>
{{ lead.fullname }}
</div>
<div class="form-control">
<label for="">Email</label>
{{ lead.email }}
</div>
<div class="form-control">
<label for="">Phone</label>
{{ lead.phone }}
</div>
<div class="form-control">
<label for="">City</label>
{{ lead.city }}
</div>
</fieldset>
<button type="submit" class="btn-pill">Submit</button>
</form>
in forms.py
class LeadForm(forms.ModelForm):
email = forms.EmailField()
class Meta:
model = Lead
fields = ['fullname', 'email', 'phone', 'city', 'contact_preference']
widgets = {'contact_preference': forms.RadioSelect }
Any help is appreciated. contact_preference is rendering FYI, I just cut the code to keep this question not that long.

Django Recaptcha fails the form validation

I'm implementing RecaptchaV3 on a Django application.
I am currently following this github(https://github.com/kbytesys/django-recaptcha3) README text to set it up.
I have a feedback form that sends an email with the subject and text.
However, when I add RecaptchaField in django form, the POST request no longer passes the form.is_valid() in views.py.
Does anyone have a thought/fix on how to overcome this problem?
Thank you in advance
forms.py
class contactForm(forms.Form):
name = forms.CharField(max_length=50, required=True, widget=forms.TextInput(attrs={'placeholder': 'Name (required)'}))
email = forms.EmailField(max_length=100, required=True, widget=forms.TextInput(attrs={'placeholder': 'Email (required)'}))
subject = forms.CharField(max_length=200, widget=forms.TextInput(attrs={'placeholder': 'Subject'}))
message= forms.CharField(max_length=1000, widget=forms.Textarea(attrs={'placeholder': 'Message'}))
captcha = ReCaptchaField()
views.py
def homepage(request):
form = contactForm()
if request.method == 'POST':
form = contactForm(request.POST)
if form.is_valid():
print("form is valid")
form = contactForm()
return render(request, 'homepage/home.html', {'form':form, 'context':context,})
template
<form class="form-horizontal" id="contactForm" method="POST" action="?">
{% csrf_token %}
<div class="form-group">
<div class="form-group">
<label for="name">Your Name (required)</label><br>
{{ form.name }}
</div>
<div class="form-group">
<label for="email">Your Email (required)</label><br>
{{ form.email }}
</div>
<div class="form-group">
<label for="subject">Subject</label><br>
{{ form.subject }}
</div>
<div class="form-group">
<label for="message">Your Message</label><br>
{{ form.message }}
</div>
</div>
<button class="btn" type="submit">SEND</button>
</form>
in the header, i've added
{% recaptcha_init %}
{% recaptcha_ready action_name='Homepage' %}

django: form.is_valid always giving error

i am working on login page but my form always gives me error, please find my code below, please see view.py it response always go to else statment of "if form.is_valid():" condition. please help
here you can see form.py
from django.contrib.auth.models import User
from django import forms
class LoginForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput)
class Meta:
model = User
fields = ['username', 'password']
this is my view.py
def login_view(request):
template_name = 'user/login.html'
form_class = LoginForm
if request.method == "POST":
form = form_class(data=request.POST)
if form.is_valid():
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
try:
login(request, user)
return redirect('user:profile')
except:
form = form_class(None)
return render(request, template_name, {'form': form, 'custom_error': 'Error'})
else:
return HttpResponse("<h1>Data is invalid</h1>")
else:
if request.user.is_authenticated():
return redirect('user:profile')
else:
form = form_class(None)
return render(request, template_name, {'form': form,})
user/login.html
{% block body %}
<div class="section">
<div class="container">
<div class="row">
<form class="form-horizontal" role="form" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="col-md-5">
<img src="{% static 'user/images/favicon.png' %}" class="img-responsive">
</div>
<div class="col-md-6">
{% include 'user/form-template.html' %}
<div class="col-sm-offset-2 col-sm-10" align="right">
<button type="submit" class="btn btn-default" autofocus>Sign In</button>
</div>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
and finally this is my form-template.html file
{% for field in form %}
<div class="col-md-8">
<div class="col-md-4">
<label>{{ field.label_tag }} </label>
</div>
<div class="col-md-4">
{{ field }}
<div>
<span>{{ field.errors }}</span>
</div>
<div>
<span class="text-danger small">{{ custom_error }}</span>
</div>
</div>
</div>
{% endfor %}
If you are using ModelForm, you are going to operate on django model objects, creating, updating, etc. If you are only trying to login, use Form instead.
Thanks its solved, I just Changed My Form no it looks like this.
class LoginForm(forms.Form):
username = forms.CharField()
password = forms.CharField(widget=forms.PasswordInput)
now i am not using built-in form and i also changed ModelForm to Form.

How insert 2 different forms on the same page in Django

I have to insert 2 forms in the same page:
1) Registration form
2) Login form
.
So if I use this in the views.py:
if request.method == 'POST':
form = registrationForm(request.POST)
if form.is_valid():
form.save()
return render_to_response('template.html', {
'form': form,
})
I will get error by submitting one of two forms.
How can I distinguish the 2 forms submitting in the views ?
You can also do like this,
<form method='POST'>
{{form1.as_p}}
<button type="submit" name="btnform1">Save Changes</button>
</form>
<form method='POST'>
{{form2.as_p}}
<button type="submit" name="btnform2">Save Changes</button>
</form>
CODE
if request.method=='POST' and 'btnform1' in request.POST:
do something...
if request.method=='POST' and 'btnform2' in request.POST:
do something...
You can submit two forms on the same page... but the action that each form calls (i.e. the view function that will process each form) should probably be different. That way, you won't have to try and distinguish the forms.
e.g. On your page:
<form id="login_form" action="{% url app.views.login %}" method="post">
...form fields...
</form>
<form id="registration_form" action="{% url app.views.registration %}" method="post">
...form fields...
</form>
And so, in views.py, you'll have a login() view function and a registration() view function that will handle each of those forms.
<form action="Page where u want to post the data" method="post">
<input name="edit" type="submit" value="Edit Client">
<input name="delete" type="submit" value="Delete Client">
</form>
just Give different names to the buttons.
if request.method == "POST" and 'edit' in request.POST:
/ Do /
if request.method == "POST" and 'delete' in request.POST:
/Do /
You can post both forms to same url too:
forms in template are like this:
<form method="post" action="/profile/">
{% for field in firstform %}
<div class="mb10">
<div class="fl desc">{{ field.label_tag }}<br />
<div class="fr">{{ field }}{{ field.errors }}</div>
<div class="clear"></div>
</div>
{% endfor %}
{% for field in secondform %}
<div class="mb10">
<div class="fl desc">{{ field.label_tag }}<br /><</div>
<div class="fr">{{ field }}{{ field.errors }}</div>
<div class="clear"></div>
</div>
{% endfor %}
<a class="submit fr" href="#""><img src="{{ MEDIA_URL }}img/save.png" /></a>
</form>
and just handle them like this in view:
if request.method == 'POST':
firstform = ProfileForm(request.POST, request.FILES, instance=profile)
secondform = UserForm(request.POST, instance=request.user)
and then do stuff with firstform&secondform.
You can have both forms posting to the same URL and have a hidden input with name set to login or registration and sort that out on the server
You can do the Registration and Login POST to different urls so each POST will be handled by corresponding view