joselegit
joselegit

Reputation: 533

Django Form validation won't work

I have a form based on a model, but the validation won't work.

When I submit the form with empty values I get the error:

KeyError 'id_proveedor'

My model:

class Cambio_Precio(models.Model):
      id_precio = models.AutoField(primary_key=True)
      id_proveedor = models.ForeignKey(Proveedor,db_column='id_proveedor', verbose_name='Proveedor')
      id_codigo = ChainedForeignKey(Codigo_Corto,chained_field="id_proveedor",chained_model_field="id_proveedor",show_all=False,auto_choose=True,verbose_name='Codigo Corto')
      anio = models.CharField(max_length=4,blank=False,null=False)
      mes = models.CharField(max_length=2,blank=False,null=False)
      dia = models.CharField(max_length=2,blank=False,null=False)
      precio_nominal = models.DecimalField(max_digits=9,decimal_places=4,blank=False,null=False)
      precio = models.DecimalField(max_digits=9,decimal_places=4,blank=False,null=False)
      revenue = models.DecimalField(max_digits=9,decimal_places=4)
      moneda = models.CharField(max_length=2)
      codigo_as = models.CharField(max_length=15,blank=True,null=True,verbose_name='Codigo AS400')
      imp_rifas = models.BooleanField(verbose_name='Imp rifas y encuestas')      
      bizflow_id = models.CharField(max_length=50,blank=True,null=True)
      estado = models.BooleanField()
      usuario = models.CharField(max_length=50)
      fecha_registro = models.DateTimeField()

My Form:

class CambioPrecioForm(forms.ModelForm):
      id_proveedor = forms.ModelChoiceField(queryset=Proveedor.objects.all().order_by('nombre'),required=True,label='Proveedor')
      anio = forms.IntegerField(label='A&ntilde:o')
      mes = forms.ChoiceField(
               choices = (
                          ('01',"Enero"),
                          ('02',"Febrero"),
                          ('03',"Marzo"),
                          ('04',"Abril"),
                          ('05',"Mayo"),
                          ('06',"Junio"),
                          ),
               widget = forms.Select(attrs={'style': 'width:100px'}),required=True
              )
      dia = forms.IntegerField(widget = forms.NumberInput(attrs={'style': 'width:80px'}),required=True)
      precio_nominal = forms.DecimalField(widget = forms.NumberInput(attrs={'style': 'width:100px'}),required=True)
      precio = forms.DecimalField(widget = forms.NumberInput(attrs={'style': 'width:100px'}),required=True)
      revenue = forms.DecimalField(widget = forms.NumberInput(attrs={'style': 'width:100px'}),required=True)
      moneda = forms.ChoiceField(
               choices = (
                          ('$',"$"),('L',"L"),
                          ),
               widget = forms.Select(attrs={'style': 'width:50px'})
             ,required=True )
      def __init__(self,*args,**kwargs):
         super(CambioPrecioForm,self).__init__(*args,**kwargs)

      class Meta:
            model = Cambio_Precio
            exclude = ['usuario','estado','fecha_registro']

      def clean(self):
          cleaned_data = super(CambioPrecioForm, self).clean()
          idp = cleaned_data['id_proveedor']
          idc = cleaned_data['id_codigo']
          mesv = cleaned_data['mes']
          diav = cleaned_data['dia']
          prenv = cleaned_data['precio_nominal']
          prefv = cleaned_data['precio']
          bizv = cleaned_data['bizflow_id']
          aniov = cleaned_data['anio']

          try:             Cambio_Precio.objects.get(id_proveedor=idp,id_codigo_id=idc,mes=mesv,dia=diav,anio=aniov)
              raise forms.ValidationError('Ya se registrado un cambio de precio para esta misma fecha')
          except Cambio_Precio.DoesNotExist:
              pass

          return cleaned_data

My view:

@login_required(login_url='/login/')
def CambioPrecioView(request):
    if request.method == 'POST':
       form = CambioPrecioForm(request.POST)
       provf = request.POST.get('id_proveedor')
       codf = request.POST.get('id_codigo')
       mesf = request.POST.get('mes')
       diaf = request.POST.get('dia')
       precionf = request.POST.get('precio_n')
       preciof = request.POST.get('precio')
       if form.is_valid():
          obj = form.save(commit=False)
          obj.usuario = request.user
          obj.estado = 0
          obj.fecha_registro = datetime.datetime.now()
          obj.save()
          alarma = Alarma_Precio()
          spalarma = alarma.precio(provf,codf,preciof)
          return HttpResponseRedirect('/home/')
    else:
       form = CambioPrecioForm()

    return render_to_response("cambioprecioform.html",
                              {'form':form},
                              context_instance=RequestContext(request))

In the form I validate the user can insert data for the same code and the same date.

The model have some fields with

Null = True, blank = True

But for the other fields I need to validate the field must be required, but doesn't work.

If I fill all the field the form works without any issue, but if oen of the required fields is empty I get an error

KeyError field_name

The error is raised when the view get to the

If form.is_valid():

Any advice or guideline will be very appreciated

Thanks in advance

Upvotes: 0

Views: 333

Answers (1)

Alasdair
Alasdair

Reputation: 309099

The problem is this section of your clean method.

def clean(self):
    cleaned_data = super(CambioPrecioForm, self).clean()
    idp = cleaned_data['id_proveedor']

You can't assume that any field will be present in cleaned_data.

You should change your code to check whether the value appears in cleaned_data before accessing it.

def clean(self):
    cleaned_data = super(CambioPrecioForm, self).clean()
    if 'id_proveedor' in cleaned_data:
        idp = cleaned_data['id_proveedor']
        # do something with idp
    else:
        # don't use idp in this branch

Upvotes: 3

Related Questions