0

After searching for a while, I can't seem to find any answer for this so I'm asking this question. What I want to is display some values based on a person's salary and a bracket. My models looks like this.

class Employee
    salary = models.DecimalField

class Benefit
    some_fields

class EmployeeBenefit
    employee = models.ForeignKey
    benefit = models.ForeignKey

class BenefitVersion
    benefit = models.ForeignKey

class BenefitBracket
    benefit_version = models.ForeignKey
    from_salary = models.DecimalField
    to_salary = models.DecimalField
    the_fields_I_want_to_display

As you can see it's quite deep, there would be a bunch of querying to do to get to the fields I want.

I basically need to get the employee's salary(which is easy because this is gonna be inside EmployeeAdmin) then get the current benefit of the EmployeeBenefit list item, then based on the benefit and the employee's salary, get the bracket and then display some of it's fields on the inline.

I want to display the the_fields_I_want_to_display on the admin.TabularInline for EmployeeBenefit inside my EmployeeAdmin. I was testing using a forms.ModelForm in the inline and modifying it's contents using get_form based on this answer but django is not calling get_form. I also previously tried using calculated_fields but it's not being rendered as well.

I'm using django 3.1.7 btw

Edit:

I found this and try it out right now. I think it has potential but unfortunately the obj that get_formset gives is Employee so I still need to find a way to get the right EmployeeBenefit for the list item

rminaj
  • 560
  • 6
  • 28

1 Answers1

1

After some more searching, I already figured out a way to do this. Based on this SO answer, I got an idea on how I should receive the data I passed to the formset using get_formset.

So, in my get_formset, I did something like this.

def get_formset(self, request, obj=None, **kwargs):
    formset = super(Inline, self).get_formset(request, obj, **kwargs)
    formset.request = request
    benefit_details_dict_arr = []

    emp_contribs = models.EmployeeBenefit.objects.filter(employee=obj)
    #because what I'm getting here is Employee and not a EmployeeBenefit, I have to query it first

    for contrib in emp_contribs:
        bracket = contrib.get_benefit_bracket(datetime.now())
        benefit_details_dict_arr.append({
            "key": bracket.val,
            "key2": bracket.val2,
        })

    formset.benefit_details = benefit_details_dict_arr

    return formset

Then on the formset, I receive the data this way.

class EmpBenefitFormSet(forms.models.BaseInlineFormSet):
    model = models.EmployeeBenefit

    def __init__(self, *args, **kwargs):
        super(EmpBenefitFormSet, self).__init__(*args, **kwargs)
        
        cntr = 0
        for form in self.forms:
            init_data = self.benefit_details[cntr]

            for field in form.fields:
                if field in init_data:
                    form.initial[field] = init_data[field]

                    form.fields[field].required = False
                    form.fields[field].disabled = True

            cntr += 1

Also, if you're gonna use this way of receiving the data, each field you want to inflate should be declared on the fields of the inline. This should work if the fields you want to set an initial value are actual fields of the model. You might need to tweak this a bit to work for custom fields

rminaj
  • 560
  • 6
  • 28