Problems to display the Form in the Template using CreateView - python

What happens is that I am using CreateView and I find it curious that the code works when I put {{form}}, it displays all the fields and saves in the database (everything works very well) but when I break down the values ​​one by one for example: {{form.plates}}, {{form.type}}, it does not send anything to the database and it stays on the same page. Why is that? I just need it broken down
clientes-add.html
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
<div class="row mb-3">
<div class="col-md-3">
<div class="mb-3">
<label>Customer type</label>
<br>
<div class="form-check form-check-inline">
{{ form.tipo }}
</div>
</div>
</div>
</div>
<div class="row mb-3 only-corp hide-item">
<div class="col-md-12">
<div class="mb-3">
<label>Corporation name</label>
{{ form.corporacion }}
</div>
</div>
</div>
<button class="btn btn-primary mb-3" type="submit" value="Post">Save</button>
</form>

You also need to render {{form.fieldname.errors}} for each {{form.fieldname}}. The error will be telling you why the form is not valid, but you cannot see them!
You can test it if there is extra html you want to generate only if there are errors.
{% if form.fieldname.errors %} <br> {{form.fieldname.errors }} {% endif %}
Don't forget {{form.non_field_errors }}

Related

How to associate form with a `bootstrap_field` outside that form?

Given this field {% bootstrap_field form.photo %} which is a forms.ImageField and the form after, I need to associate the field with the form in a way that when the form is submitted, I get the value in form.photo.
<div class="row container h-100">
<div class="col-xl-4">
<div class="card mb-4 mb-xl-0">
<div class="card-body text-center">
<img style="max-width: 50%" alt="Avatar" class="img-account-profile rounded-circle mb-2"
src={{ request.user.profile.photo.url }}>
{% bootstrap_field form.photo %}
</div>
</div>
</div>
<div class="col h-100">
<div class="card shadow-lg">
<div class="card-body p-5">
<form enctype="multipart/form-data" method="post">
{% csrf_token %}
<div class="row">
<span class="col">
{% bootstrap_field form.first_name %}
</span>
<span class="col">
{% bootstrap_field form.last_name %}
</span>
<button class="btn btn-success col">Update</button>
</div>
</form>
</div>
</div>
</div>
</div>
Currently if a photo is uploaded, it won't show up in the form response because it's not included within <form></form>. I need it to be outside the form because the locations of the form fields and the photo are different.
One way to do so is to wrap both cards inside the form tags. Is this the best way to do it or is there a simpler way like specifying {% bootstrap_field my_field form=my_form %}

Flask apply filter with multiple checkboxes

Hey good people of stackoverflow,
My application randomly selects a recipe from MongoDB (using pymongo) and displays it to the user.
My intention is to be able to apply filters (vegetarian, fish, beef and so on) to the next "random" selection after hitting Something else button.
I think I can achieve it by using request.form.getlist and creating the form in the pick_meal.html but it feels a bit overkill.
So far I am unable to figure it out.
Any help would be greatly appreciated.
The html and python function looks like this:
{% extends 'base.html' %}
{% block content %}
<div class="container">
<h3>{% block title %} You should cook: {% endblock %}</h3>
<div class="row">
<div class="col-md-5 align-self-center text-center">
<span>{{ dish.dish_name }}</span>
</br>
</br>
<a class="btn btn-outline-success" href="{{ dish['dish_source'] }}" role="button">Go to web</a>
</div>
<div class="col-md-4">
<img src="{{ dish.dish_image }}" width="250px">
</div>
</div>
</br>
<div class="row">
<div class="col-md-5">
<button class="btn btn-primary">Something else</button>
<button class="btn btn-primary">Configrm choice</button>
<button class="btn btn-primary">Already cooked</button>
</div>
<div class="col-md-5">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="vegetarian" id="flexCheckDefault" name="property_checkbox">
<label class="form-check-label" for="flexCheckDefault">Vegetarian</label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" value="grill" id="flexCheckDefault" name="property_checkbox">
<label class="form-check-label" for="flexCheckDefault">Grill</label>
</div>
</div>
</div>
</div>
{% endblock %}
#app.route('/pick_meal/<string:dish_type>')
def pick_meal(dish_type):
# pick random meal based on category
dish = list(coll.aggregate([
{'$match':{
'cooked': False,
'dish_type': dish_type}},
{ '$sample':{
'size': 1 } }]))[0]
return render_template('pick_meal.html', dish=dish, dish_type=dish_type)

Django-messages works only when form|crispy is used but not in other cases

I am creating a login page using django but it does not show any messages when I enter wrong passwords or email addresses. I've also checked other messages but it didn't help.
login.html
<div class="right">
<h2>Login</h2>
{% if messages %}
{% for message in messages %}
<div class="alert alert-{{ message.tags }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<div class="field">
<div class="label">Email or Username</div>
<input type="text" name="username" id="username" class="form-control">
</div>
<div class="field">
<div class="label">Password</div>
<input type="password" name="password" id="password" class="form-control">
</div>
<button class="login" type="submit">LOGIN</button>
</fieldset>
</form>
<div class="sign_up">
<small>Don’t have an account yet?</small>
<a class="signup" href="{% url 'register' %}">SIGN UP</a>
</div>
</div>
urls.py has this path for the login page(I have imported all the necessary classes):
path('login/', auth_views.LoginView.as_view(template_name='users/login.html') , name='login'),
But the messages are shown when I use this form|crispy in login.html
<div class="content-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Login</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Sign In</button>
</div>
</form>
<div class="border-top pt-3">
<small class="muted-text">
Want a new Account? <a class="ml-1" href="{% url 'register' %}">Sign Up</a>
</small>
</div>
</div>
Here you used LoginView using form it will return it will show you error because of {{ form|crispy }} template tag render form and fields along with field.errors and field.non_field_error.
That's Why you can get an error message if you remove message block in your code it will show you an error there is no connection with form and message in login view
If you want to render you HTML form with CSS you need to explicitly define errors showing block like this
<div class="right">
<h2>Login</h2>
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endfor %}
{% for error in form.non_field_errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<div class="field">
<div class="label">Email or Username</div>
<input type="text" name="username" id="username" class="form-control">
</div>
<div class="field">
<div class="label">Password</div>
<input type="password" name="password" id="password" class="form-control">
</div>
<button class="login" type="submit">LOGIN</button>
</fieldset>
</form>
<div class="sign_up">
<small>Don’t have an account yet?</small>
<a class="signup" href="{% url 'register' %}">SIGN UP</a>
</div>
</div>
Here not meaning to use the message framework of Django. Form it self return error in his errors attribute of a form
Hope you satisfied with this answer

error is not displayed in the template

I have used django allauth for user registration and login. I have used the {{ form.has_errors }} in template to show an error but the error is not displayed in the template. What might be the reason for not showing an error in the template?
The code from allauth login.html(account/login.html)
{% block content %}
<div class="login-box">
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-6 col-md-offset-3 login-area">
<span class="error">
{% if form.has_errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
</span>
<div class="panel panel-default">
<div class="panel-heading login-header">{% trans "Sign In" %}</div>
<div class="panel-body">
<form class="login" method="POST" action="{% url 'account_login' %}">
{% csrf_token %}
<div class="form-group form-group-lg">
<label for="emailAddress">Email address</label>
<input type="email" class="form-control" id="emailAddress id_login" name="login" placeholder="Email">
</div>
<div class="form-group form-group-lg">
<label for="password">Password</label>
<input type="password" class="form-control" id="password id_password" name="password" placeholder="Password">
</div>
<div class="form-group">
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}
</div>
<button class="btn-block signin-btn btn-sm btn-primary pull-right m-t-n-xs" type="submit">{% trans "Sign In" %}</button>
</form>
</div>
<div class="panel-footer">
<a class="button secondaryAction" href="{% url 'account_reset_password' %}">{% trans "Forgot Password?" %}</a>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Try this one. Errors raised by the form which is not attached to field are stored in non_field_errors
{% if form.non_field_errors %}
<ul class='form-errors'>
{% for error in form.non_field_errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
or if you want to display in your way try this one
{% if form.errors %}
<p>Your username and password didn't match. Please try again.</p>
{% endif %}
Seems to be a misunderstanding of has_error
his method returns a boolean designating whether a field has an error
with a specific error code. If code is None, it will return True if
the field contains any errors at all.
Coupled with the fact that you are rendering the form manually. Generally there are two types of form errors, non field errors and errors associated with each field (when their validation fails). The above method accepts a field name as a parameter and returns true if the field has failed validation.
You have several options, including continuing with your current approach but checking for form.errors instead of form.has_error or displaying the error with each field separately.

Styling forms using Django and Bootstrap

Okay, so I've created a simple purchase form which makes use of some custom form fields. I've rendered a simple form to test if it works properly, and it does, as shown below.
<form id="category_form" method="post" action="/purchase/">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text }}
{{ field }}
{% endfor %}
<input type="submit" name="submit" value="Make purchase" />
</form>
Now, I wish to style it to Bootstrap 3. I've managed to style it with no problems using the django widget tweaks package. However, when I submit the form, I get this error 'NoneType' object has no attribute 'replace' I've tried it without the widget tweaks and I still get the same error.
Any ideas why this may be the case? The original form works fine unstyled, but as soon as I style it I get the above error. Now if my understanding is correct, Django takes one field and styles corresponding fields the same, but, some of my field types are different. i.e. dropdowns and text boxes, which can't be styled the same way. I'm not sure what the best way around this is.
views.py
def checkout(request):
if request.method == 'POST':
form = PurchaseForm(request.POST)
if form.is_valid():
form.save(commit=True)
return index(request) # Change this to point to the confirmation page
else:
print (form.errors)
else:
form = PurchaseForm()
return render(request, 'ticket/checkout.html', {'form': form})
checkout.html
<form class="form-horizontal" method="post" action="/cart/checkout/">
{% csrf_token %}
<fieldset>
<!-- Form Name -->
<legend>Card Details</legend>
<!-- Select Basic -->
<div class="form-group">
<label class="col-sm-3 control-label" for="card-type">{{ form.payment_type.help_text }}</label>
<div class="col-sm-9">
{{ form.payment_type|attr:"id:card-type"|attr:"name:card-type"|attr:"class:form-control" }}
{{ form.error }}
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-sm-3 control-label" for="card-name">{{ form.card_name.help_text }}</label>
<div class="col-sm-9">
{{ form.card_name|attr:"id:card-name"|attr:"name:card-name"|attr:"type:text"|attr:"placeholder:Card Holder's Name"|attr:"class:form-control input-md"|attr:"required:"}}
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-sm-3 control-label" for="card-number">{{ form.card_number.help_text }}</label>
<div class="col-sm-9">
{{ form.card_number|attr:"id:card-number"|attr:"name:card-number"|attr:"type:text"|attr:"placeholder:Credit / Debit card number"|attr:"class:form-control input-md"|attr:"required:"}}
</div>
</div>
<!-- Select Basic -->
<div class="form-group">
<label class="col-sm-3 control-label" for="expiry-date">{{ form.expiry_date.help_text }}</label>
<div class="col-sm-4">
{{ form.expiry_date|attr:"id:expiry-date"|attr:"name:expiry-date"|attr:"class:form-control col-sm-4" }}
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-sm-3 control-label" for="cvv-number">{{ form.security_code.help_text }}</label>
<div class="col-sm-9">
{{ form.security_code|attr:"id:cvv-number"|attr:"name:cvv-number"|attr:"type:text"|attr:"placeholder:Security Code"|attr:"class:form-control input-md"|attr:"required:"}}
</div>
</div>
<div class="form-group">
<label class="col-sm-3 control-label" for="date">{{ form.date.help_text }}</label>
<div class="col-sm-9">
{{ form.date|attr:"id:date"|attr:"name:date"|attr:"class:form-control input-md"|attr:"required:"}}
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label" for="Purchase"></label>
<div class="col-md-8">
<button id="Purchase" name="Purchase" class="btn btn-success">Purchase</button>
<button id="Cancel" name="Cancel" class="btn btn-inverse">Cancel</button>
</div>
</div>
</fieldset>
I would suggest using the python package django-bootstrap3 to style your forms. It can be found at https://github.com/dyve/django-bootstrap3
Hope this helps!
I am not sure whether I understand your question correctly. However I noticed that 1. there seems no tag in your form.
2. maybe you can use plain html instead of other tag( {{ form.security_code|attr:"id:cvv-number"|attr:"name:cvv-number" ****}} ), such as
3. to validate form, you may try to write something like :
{% if form.password.errors %}
{% for error in form.password.errors %} {{ error}} {% endfor %} {% endif %}
Hope you figure out this problem as soon as possible.

Categories