django admin 'Form' has no field named 'field_name' when resaving a record

Viewed 580

As the title goes, when I was resaving a record, I'm getting an error saying

ValueError: 'EmployeeLeaveForm' has no field named 'start_date'.

which should be impossible because I got a check to ensure that it's filled up in clean(). Initial save works fine, but when I try to resave it, the error I mentioned earlier appears

Here's my complete form:

class EmployeeLeaveForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        if 'initial' not in kwargs:
            kwargs['initial'] = {}

        request = self.request
        is_hr = request.user.groups.all().filter(name__icontains="HR").exists()
        is_superuser= request.user.is_superuser

        #set initial values to fields when user is not authorized to change the employee field
        if not is_hr and not is_superuser:
            kwargs['initial'].update({'employee': self.employee})
            kwargs['initial'].update({'employee_paid_leave': self.employee_paid_leave})

        super(EmployeeLeaveForm, self).__init__(*args, **kwargs)

        self.fields['employee_paid_leave'].required = False
        self.fields['employee_paid_leave'].disabled = True

        if not is_hr and not is_superuser:
            #for making employee readonly
            self.fields['employee'].required = False
            self.fields['employee'].disabled = True
            self.fields['employee'].widget = LeaveEmployeeReadOnlyWidget()
            

    def clean(self):
        start_date = self.cleaned_data.get('start_date')
        end_date = self.cleaned_data.get('end_date')
        type = self.cleaned_data.get('type')
        employee = self.cleaned_data.get('employee')

        #for some reason, I think read only makes a field seem None
        if self.instance.pk is None and employee.paid_leave_balance <= 0:
            raise forms.ValidationError("Insufficient paid leave balance")

        if start_date is None:
            raise forms.ValidationError({'start_date': ["Start date is empty",]})
        elif end_date is None:
            raise forms.ValidationError({'end_date': ["End date is empty",]})
        elif type is None:
            raise forms.ValidationError({'type': ["Leave type is empty",]})
    
    employee_paid_leave = forms.FloatField(label = 'Remaining Paid Leave', required = False)

    class Meta:
        model = models.EmployeeLeave
        exclude = []
        fields = [
            "employee",
            "start_date",
            "start_date_half_day",
            "end_date",
            "end_date_half_day",
            "type",
            "approved_by_supervisor",
            "approved_by_department",
            "reason",
            "deducted",
        ]

        #for adding the custom field
        fields = fields[:1] + ['employee_paid_leave',] + fields[1:]

    class Media:
        js = ('/static/js/jquery.js', '/static/js/custom_admin_validate.js')

I'm also suspecting that making the field readonly somehow made them seem None because when I tried to remove start_date from the readonly_fields, it doesn't throw an error for that field.

Could this be an internal django issue?

1 Answers

As I suspected, Django doesn't give a readonly_field the same field as a normal field. The field given to readonlys doesn't have the functionalities a non-readonly field have which includes the functionality to read the contents of it.

https://code.djangoproject.com/ticket/30373

Related