Django empty form field validation is not working with clean method

12,537

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,
                                })  
Share:
12,537

Related videos on Youtube

jsanchezs
Author by

jsanchezs

Ingeniero de software, desarrollador de videojuegos en tiempo libre. Software Enginner, videogame developer on free time.

Updated on July 14, 2022

Comments

  • jsanchezs
    jsanchezs almost 2 years

    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">&times;</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

    • Shang Wang
      Shang Wang about 8 years
      Also, you are always returning empty forms, which is no good. You should return the form when it failed the validation as well.
  • jsanchezs
    jsanchezs about 8 years
    Nope, doesn't work either...it always takes me to the message "could not create record" in the view when i try to save leaving description empty =(
  • Sayse
    Sayse about 8 years
    @jsanchezs - It might be worth setting a breakpoint then to make sure you enter the method (using an IDE such as pycharm), having said that, setting it in the model would be better option anyway imo
  • Shang Wang
    Shang Wang about 8 years
    You need to print form_insert.errors to see if there's any other things other than your clean method that failed the validation.
  • Sayse
    Sayse about 8 years
    @jsanchezs - Actually, That message is correct isn't it? You can't create a record if description is empty... I thought that is what you wanted? Also see Shang Wang's comment about returning the form
  • jsanchezs
    jsanchezs about 8 years
    Yeah, but isn't validation error supossed to show the alert inside the form before user can proceed to save ??... already did the breakpoint printing form_insert.errors and got this : '<ul class="errorlist"><li>description<ul class="errorlist"><li>Este campo es obligatorio.</li></ul></li></ul>' meaning field is required, already tried blank=false too
  • Sayse
    Sayse about 8 years
    @ShangWang - I kind of edited my answer based off your comment so if you want to make your own by copying what is below the break in my answer, feel free
  • Sayse
    Sayse about 8 years
    @jsanchezs - I've updated my answer, but please if ShangWang creates one, accept that instead of this
  • jsanchezs
    jsanchezs about 8 years
    Thanx @ShangWang Did that but still not working, it's so weird, logically everything is in order =S
  • Sayse
    Sayse about 8 years
    @jsanchezs - What does "not working" mean now? What do you have in your template? Do you just show your form with {{ form_cost_item }}? If not please update your question with your template
  • jsanchezs
    jsanchezs about 8 years
    @Sayse thanks for your help. What i have is a costitem.html template, got a input button that calls a modal where the form is shown, then when i try to save from the modal only leaving description empty, it takes me back to the costitem.html showing the message of the view " could not create record", but it never alerts about the empty inside the form...i know thatś correct too, but i want the alert to be displayed inside the form and before user can save.
  • Sayse
    Sayse about 8 years
    @jsanchezs - Please update your question with the relevant parts of your template (i.e your form)
  • jsanchezs
    jsanchezs about 8 years
    @Sayse ok, i did it know adding the modal code from where i call the form and later the view to save

Related