[Django]-Evaluate a readonly field upon creating a new object in Django 1.11 admin

2👍

Instead of custom form you can use ModelAdmin‘s save_model method:

 class PersonAdmin(admin.ModelAdmin):

    def save_model(self, request, obj, form, change):
        birthdate = form.cleaned_data.get('birthdate')
        age = relativedelta(datetime.date.today(), birthdate).years 
        obj.age = age
        super().save_model(request, obj, form, change)

    def get_exclude(self, request, obj=None):
        if not obj:
            return ('age',)
        return self.exclude  

Also you probably can use readonly_fields:

 class PersonAdmin(admin.ModelAdmin):
    readonly_fields = ('age',)

    def save_model(self, request, obj, form, change):
        birthdate = form.cleaned_data.get('birthdate')
        age = relativedelta(datetime.date.today(), birthdate).years 
        obj.age = age
        super().save_model(request, obj, form, change)

1👍

Or you can hide the input from form.

# admin.py
from django.contrib import admin
from django import forms
from .models import Person
from dateutil.relativedelta import relativedelta
import datetime

class PersonForm(forms.ModelForm):
    age = forms.CharField(widget=forms.HiddenInput, required=False)
    def clean(self):
        cleaned_data = super(PersonForm, self).clean()
        birthdate = cleaned_data.get('birthdate')
        cleaned_data['age'] = relativedelta(datetime.date.today(), birthdate).years
        return cleaned_data

You can use that form only when object is none (create case).

class PersonAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if not obj:
            kwargs['form'] = PersonForm
        return super().get_form(request, obj, **kwargs)

admin.site.register(Person, PersonAdmin)

Leave a comment