Форма Django: десятичные числа, разделенные запятыми, выдают ошибки проверки

#python #python-3.x #django #django-forms

#python #python-3.x #джанго #django-формы #django #django-forms

Вопрос:

У меня есть форма, в которой пользователь может вводить десятичные / целочисленные значения через запятую, например, 500 000 или 500 000,00. Когда я обрабатываю поле с помощью Django ModelForm, оно выдает ошибку проверки, например Enter a number , «Я хочу удалить эти «,» прежде чем значение попадет в базу данных.Поля join_bonus и var_pay имеют атрибут required=False , но все же эти поля вызывают «Это поле обязательно». ошибка проверки.

Моя форма:

 class EmployeeSalaryForm(forms.ModelForm):
    class Meta:
        model = Salary
        fields = [
            'basic_salary',
            'convyence_allowance',
            'medical_allowance',
            'mobile_allowance',
            'executive_allowance',
            'gross_salary',
            'epf',
            'health_benefit',
            'ctc',
            'join_bonus',
            'var_pay',
        ]

        
        basic_salary = forms.DecimalField(max_digits=11,decimal_places=2)
        convyence_allowance = forms.DecimalField(max_digits=11,decimal_places=2)
        medical_allowance = forms.DecimalField(max_digits=11,decimal_places=2)
        mobile_allowance = forms.DecimalField(max_digits=11,decimal_places=2)
        executive_allowance = forms.DecimalField(max_digits=11,decimal_places=2)
        gross_salary = forms.DecimalField(max_digits=11,decimal_places=2)
        epf = forms.DecimalField(max_digits=11,decimal_places=2)
        health_benefit = forms.DecimalField(max_digits=11,decimal_places=2)
        ctc = forms.DecimalField(max_digits=11,decimal_places=2)
        join_bonus = forms.DecimalField(max_digits=11,decimal_places=2, required=False)
        var_pay = forms.DecimalField(max_digits=11,decimal_places=2, required=False)
        

        def clean_basic_salary(self):
            basic_salary = self.cleaned_data['basic_salary']

            return basic_salary.replace(',', '')

        def clean_convyence_allowance(self):
            convyence_allowance = self.cleaned_data['convyence_allowance']

            return convyence_allowance.replace(',', '')

        def clean_medical_allowance(self):
            medical_allowance = self.cleaned_data['medical_allowance']

            return medical_allowance.replace(',', '')

        def clean_mobile_allowance(self):
            mobile_allowance = self.cleaned_data['mobile_allowance']

            return mobile_allowance.replace(',', '')

        def clean_executive_allowance(self):
            executive_allowance = self.cleaned_data['executive_allowance']

            return executive_allowance.replace(',', '')

        def clean_gross_salary(self):
            gross_salary = self.cleaned_data['gross_salary']

            return gross_salary.replace(',', '')

        def clean_epf(self):
            epf = self.cleaned_data['epf']

            return epf.replace(',', '')

        def clean_health_benefit(self):
            health_benefit = self.cleaned_data['health_benefit']

            return health_benefit.replace(',', '')

        def clean_ctc(self):
            ctc = self.cleaned_data['ctc']

            return ctc.replace(',', '')

        def clean_join_bonus(self):
            join_bonus = self.cleaned_data['join_bonus']

            return 0 if join_bonus == None else join_bonus.replace(',', '')

        def clean_var_pay(self):
            var_pay = self.cleaned_data['var_pay']

            return 0 if var_pay == None else var_pay.replace(',', '')
  

Модель заработной платы:

 class Salary(models.Model):
    class Meta:
        db_table = 'emp_salary_master'

    employee = models.ForeignKey(Employee, on_delete=models.CASCADE)

    basic_salary = models.DecimalField(max_digits=11, decimal_places=2)

    hra = models.DecimalField(max_digits=11, decimal_places=2)

    convyence_allowance = models.DecimalField(max_digits=11, decimal_places=2)

    medical_allowance = models.DecimalField(max_digits=11, decimal_places=2)

    mobile_allowance = models.DecimalField(max_digits=11, decimal_places=2)

    executive_allowance = models.DecimalField(max_digits=11, decimal_places=2)

    gross_salary = models.DecimalField(max_digits=11, decimal_places=2)

    epf = models.DecimalField(max_digits=11, decimal_places=2)

    health_benefit = models.DecimalField(max_digits=11, decimal_places=2)
    
    ctc = models.DecimalField(max_digits=11, decimal_places=2)
    
    join_bonus = models.DecimalField(max_digits=11, decimal_places=2, default=0)
    
    var_pay = models.DecimalField(max_digits=11, decimal_places=2, default=0)
    
    to_date = models.DateField()

    from_date = models.DateField()

    created_at = models.DateField(auto_now_add=True)
    updated_at = models.DateField(auto_now_add=True)
  

Ответ №1:

Попробуйте выполнить приведение типов:

 def clean_basic_salary(self):
    basic_salary = self.cleaned_data['basic_salary']

    return int(basic_salary.replace(',', ''))

def clean_convyence_allowance(self):
    convyence_allowance = self.cleaned_data['convyence_allowance']

    return int(convyence_allowance.replace(',', ''))

def clean_medical_allowance(self):
    medical_allowance = self.cleaned_data['medical_allowance']

    return int(medical_allowance.replace(',', ''))

def clean_mobile_allowance(self):
    mobile_allowance = self.cleaned_data['mobile_allowance']

    return int(mobile_allowance.replace(',', ''))

def clean_executive_allowance(self):
    executive_allowance = self.cleaned_data['executive_allowance']

    return int(executive_allowance.replace(',', ''))

def clean_gross_salary(self):
    gross_salary = self.cleaned_data['gross_salary']

    return int(gross_salary.replace(',', ''))

def clean_epf(self):
    epf = self.cleaned_data['epf']

    return int(epf.replace(',', ''))

def clean_health_benefit(self):
    health_benefit = self.cleaned_data['health_benefit']

    return int(health_benefit.replace(',', ''))

def clean_ctc(self):
    ctc = self.cleaned_data['ctc']

    return int(ctc.replace(',', ''))

def clean_join_bonus(self):
    join_bonus = self.cleaned_data['join_bonus']

    return 0 if join_bonus == None else int(join_bonus.replace(',', ''))

def clean_var_pay(self):
    var_pay = self.cleaned_data['var_pay']

    return 0 if var_pay == None else int(var_pay.replace(',', ''))

  

Поскольку вы создали эти поля как десятичное поле, вы можете вводить только значения int или float. Когда вы получаете данные из обычной формы, они представляются в виде строк. Поэтому для решения этой проблемы вам нужно либо использовать приведение типов, либо использовать формы модели Django. Надеясь, что это решит проблему. Спасибо!

Комментарии:

1. Спасибо за ваш ответ, но он не будет работать, потому что эти методы запускаются после установки значений. Поскольку эти поля ожидают десятичное значение, оно будет продолжать вызывать ошибки проверки.

Ответ №2:

Это немного старый вопрос, я хотел бы поделиться своим решением следующим образом

Сначала создайте пользовательское десятичное поле

 class CustomDecimalField(forms.DecimalField):
    def to_python(self, value):
        return super().to_python(value.replace(',', ''))
  

Затем используйте это CustomDecimalField в вашей форме.