Reputation: 2070
I got a django form and i want to validate that fields are not empty when im going to save, let's say for example the "description" field (charfield)....this is my form.py code :
from django.core.exceptions import ValidationError
class CostItemsForm(ModelForm):
groupid = forms.CharField(required=True)
def __init__(self, *args, **kwargs):
super(CostItemsForm, self).__init__(*args, **kwargs)
class Meta:
model = CostItems
fields = [
'description',
'usd_value',
'rer',
'pesos_value',
'supplier',
'position',
'observations',
'validity_date',
]
def clean_description(self):
des = self.cleaned_data['description']
if des==None:
raise ValidationError("Description cannot be empty")
return des
But nothing happens, already tried returning like this: return self.cleaned_data
and return clean_description
but still the same.
This is my view.py:
class CostItemInsert(View):
template_name='cost_control_app/home.html'
def post(self, request, *args, **kwargs):
if request.user.has_perm('cost_control_app.add_costitems'):
form_insert = CostItemsForm(request.POST)
if form_insert.is_valid():
form_save = form_insert.save(commit = False)
form_save.save(force_insert = True)
messages.success(request, "Record created")
else:
messages.error(request, "Could not create record, please check your form")
else:
messages.error(request, "Permission denied")
form_group = GroupsForm()
form_subgroup= SubGroupsForm()
form_cost_item = CostItemsForm()
return render(request, self.template_name,{
"form_subgroup":form_subgroup,
"form_cost_item":form_cost_item,
"form_group":form_group,
})
And the costitems model :
class CostItems(ModelAudit):
cost_item = models.AutoField(primary_key = True, verbose_name = 'Item de costo')
group = models.ForeignKey(Groups, verbose_name = 'Grupo')
description = models.CharField(max_length = 100, verbose_name =' Descripcion')
usd_value = models.IntegerField(verbose_name ='Valor en USD')
rer = models.IntegerField(verbose_name = 'TRM negociado')
pesos_value = models.IntegerField(verbose_name = 'Valor en pesos')
supplier = models.ForeignKey(Suppliers, verbose_name = 'Proveedor')
position = models.ForeignKey(Positions, verbose_name = 'Cargo')
observations = models.TextField(max_length = 500, verbose_name = 'Observación')
validity_date = models.DateField(verbose_name = 'Fecha de vigencia')
def __str__(self):
return self.description
class Meta:
ordering = ['cost_item']
verbose_name = 'Item de costos'
verbose_name_plural = 'Items de costo'
And here is the modal code i call from a input button inside the html template where i call the view :
<div class="modal fade bs-example-modal-lg" id="myModals" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Registrar item de costo</h4>
</div>
<form method="post" action="{% url 'cost_control_app:cost_item_insert' %}">
{% csrf_token %}
<div class="modal-body">
<br/>
<div class="row">
{%include "partials/field.html" with field=form_cost_item.groupid|attr:"readonly:True" %}<br clear="all"/>
{%include "partials/field.html" with field=form_cost_item.description %}<br clear="all"/>
{%include "partials/field.html" with field=form_cost_item.usd_value|attr:"value:0"|attr:"id:id_usd_value" %}<br clear="all"/>
{%include "partials/field.html" with field=form_cost_item.rer|attr:"value:0"|attr:"id:id_rer_value" %}<br clear="all"/>
{%include "partials/field.html" with field=form_cost_item.pesos_value|attr:"value:0"|attr:"id:id_pesos_value" %}<br clear="all"/>
{%include "partials/field.html" with field=form_cost_item.supplier %}<br clear="all"/>
{%include "partials/field.html" with field=form_cost_item.position %}<br clear="all"/>
{%include "partials/field.html" with field=form_cost_item.observations %}<br clear="all"/>
{%include "partials/field.html" with field=form_cost_item.validity_date %}<br clear="all"/>
</br>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
<button type="submit" class="btn btn-primary">Guardar</button>
</div>
</form>
</div>
</div>
</div>
Last, partials/fields.html too :
{% load widget_tweaks%}
<div class="col-md-10">
<div class="form-group {% if field.errors %}has-error{% endif %}">
<label class="col-sm-2 control-label">{% if field.field.required %}{% endif %}{{ field.label }}<label style="color:red">*</label></label>
<div class="col-sm-10">
{% if type == 'check' %}
{{ field|add_class:"check" }}
{% elif type == 'radio' %}
{{ field|add_class:"radio" }}
{% else %}
{{ field|add_class:"form-control" }}
{% endif %}
</div>
{% for error in field.errors %}
<div class="error_msg">- {{ error }}</div>
{% endfor %}
</div>
</div>
Any help ?
Thanks in advance
Upvotes: 3
Views: 14028
Reputation: 268
If you are trying to show the form errors in the template you should pass the errors to the template. In your case the view should be something like the following.
def post(self, request, *args, **kwargs):
if request.user.has_perm('cost_control_app.add_costitems'):
form_insert = CostItemsForm(request.POST)
if form_insert.is_valid():
form_save = form_insert.save(commit = False)
form_save.save(force_insert = True)
messages.success(request, "Record created")
else:
messages.error(request, "Could not create record, please check your form")
form_group = GroupsForm()
form_subgroup= SubGroupsForm()
return render(request, self.template_name,{
"form_subgroup":form_subgroup,
"form_cost_item":form_insert,
"form_group":form_group,
})
else:
messages.error(request, "Permission denied")
form_group = GroupsForm()
form_subgroup= SubGroupsForm()
form_cost_item = CostItemsForm()
return render(request, self.template_name,{
"form_subgroup":form_subgroup,
"form_cost_item":form_cost_item,
"form_group":form_group,
})
I can see that the fields in the model are required fields by default. So anyway it will raise validation error. All you need to do is to pass the error form to template if form is invalid as above.
Upvotes: 0
Reputation: 43330
des never will equal None
, the default value will at least be an empty string
if not des:
should be enough to satify your if statement when des is empty
If all you really want to check is if its empty or not you can do that in the model by setting blank
to False
description = models.CharField(max_length = 100, blank=False, verbose_name =' Descripcion')
If a field has blank=True, form validation will allow entry of an empty value. If a field has blank=False, the field will be required.
Yeah, but isn't validation error supossed to show the alert inside the form before user can proceed to save ??
Yes it is but you override the form before it is ever shown to the user, this can easily be solved by defining the forms at the top of your method then overriding them further down
def post(self, request, *args, **kwargs):
form_group = GroupsForm()
form_subgroup= SubGroupsForm()
form_cost_item = CostItemsForm()
if request.user.has_perm('cost_control_app.add_costitems'):
form_cost_item = CostItemsForm(request.POST)
if form_cost_item.is_valid():
form_save = form_cost_item.save(commit = False)
form_save.save(force_insert = True)
messages.success(request, "Record created")
else:
messages.error(request, "Could not create record, please check your form")
else:
messages.error(request, "Permission denied")
return render(request, self.template_name,{
"form_subgroup":form_subgroup,
"form_cost_item":form_cost_item,
"form_group":form_group,
})
Upvotes: 6