Initial value in inline form depending on foreign key value

292 views
Skip to first unread message

FraMazz

unread,
Mar 12, 2012, 6:24:49 AM3/12/12
to django...@googlegroups.com
Hi all! I' m quite new to django. I googled a bit around but was not able to find an anser to my problem.

I have two models:
class Patient(models.Model):
   ... many fields ...

class Checkup(models.Model):
  ... many fields ...
  patient = models.ForeignKey(Patient, related_name='checkups')
  alcool = models.IntegerField(default=1)
  date = models.DateField()

I define an admin model for Checkup because I want it inlined in Patient

class CheckupInLineAdmin(admin.StackedInline):
  model = Checkup
  extra = 1

class PatientAdmin(admin.ModelAdmin):
 ... other fields...
inlines = [
        VisitaInLineAdmin,
    ]

When I modify a Patient, I get the inline showing his/her checkups.
Is there a way to pre-populate a field (alcool) when inserting a new inline Checkup, based on the value of the last inserted one?
Let's suppose I have Patient John Doe. He did two checkups
Checkup #1:
date: 2012/01/01
alcool: 3

Checkup #2:
date: 2012/02/02
alcool:2

I would like, when I modify John Doe through the admin interface, that the new empty inline Checkup shows a pre-populated value of 2 for the alcool field (the last inserted one for that patient)
Currently I get 1, because i defined 1 as the default value

How can I get this?

Thanks, FraMazz


FraMazz

unread,
Mar 15, 2012, 6:30:46 AM3/15/12
to django...@googlegroups.com
Well, I got it. In a very UGLY way, but it does its job.
I modified the inline class so that it gets access to the request object by overriding the get_formset function


class CheckupInLineAdmin(admin.StackedInline):
    model = Checkup
    form =CheckupAdminForm
    extra = 1

    def get_formset(self, request, obj=None, **kwargs):
        self.form.request=request
        return super(CheckupInLineAdmin, self).get_formset(request, obj, **kwargs)



Then I defined a form for this class overriding the __init__ function to give proper initial values:

class CheckupAdminForm(forms.ModelForm):
    class Meta:
        model = Checkup

        def __init__(self, *args, **kwargs):
            super(CheckupAdminForm, self).__init__(*args, **kwargs)
            # if it is not an instance (an already saved object)
            if not kwargs.has_key('instance'):
                # get patient id from request path
                # UGLY but I did not find a better way...
                # the request path is something like
                # /admin/myapp/patient/1/
                # where 1 is the patient id
                splitted = self.request.META['PATH_INFO'].split('/')
                # check the last bit is a int
                # this is useful when creating a new patient. In this case
                # the request path is
                # /admin/myapp/patient/add/ and the last bit is not the patient id
                try:
                    id_pat = int(splitted[len(splitted)-2])
                    pat = Patient.objects.get(id=id_pat)
                    checkups = pat.checkups.all()
                    how_many = len(checkups)
                    # take the last checkup
                    if how_many > 0:
                        checkup = checkups[how_many - 1]
                        # initialize fields depending on the last chechup values
                        self.initial['alcol'] = checkup.alcol
                except:
                    pass

If someone knows a better way, any hint is appreciated.
Cheers
FraMazz
Reply all
Reply to author
Forward
0 new messages