Show a model property with setter as editable in admin

Let’s say I have a model with a property for which I have defined both a getter and a setter.

I am able to see that property in the admin panel for instances of that model by adding the name of that property to the readonly_fields attribute of the relevant ModelAdmin class.

Is there a way I could also make that property editable in admin? My idea would be to have a form field (among all the others for the regular attributes) and enter a value for that property, which would then be passed to the setter for that property and the relevant code would be executed. Can this be done at all?

I haven’t been able to find much about this despite looking around for a while.

What is the real issue you’re trying to resolve here?

The Django-standard method of “doing stuff” with data submitted in a form before saving it in the model is through the form validation routines - clean() and clean_<field>().

I’m making a school system app that allows students to train for upcoming exams. The main models are Courses, Topics, and Questions (inheriting from an AbstractItem model). In addition to belonging to a Topic, Questions also have a difficulty level.

Teachers can create TrainingTemplates, which are combination of TrainingTemplateRules. A rule refers to a topic and has an amount and a difficulty profile. What it’s essentially saying is, "when I train using this template, I want 5 questions coming from topic xyz, and I want MOSTLY_HARD questions.

My custom manager for those rules takes in a total amount value and a difficulty profile (which are python dictionaries defined here), and fills in fields that are named amount_<difficulty_level_name> on the rule model. The amount doesn’t actually appear on the model because it’s just a property–the sum of the values of those fields.

For my own convenience (testing, mainly), I’d like to be able to edit that amount parameter in the admin panel, and have the values for the fields amount_<difficulty_level_name> re-calculated (using the same logic as in the manager create method).

If that sounds a little too contrived, it may be because:

  1. I suck at explaining myself sometimes (in which case, just ask away anything that still isn’t clear)
  2. what I’m doing is indeed more complicated than it needs to be—this may be off topic, but since this whole app is still at the very first stages of development, I am still unsure about some decisions that I made. The basic idea is that a student should be able to generate a quiz made up of random questions, and be able to specify upfront the amount of questions for each topic of the course that they want to see, and for each topic, also if they want only/mostly hard/easy questions or a balanced mix. The challange I’m facing is building a system that can represent that data (which I’m doing using the TrainingTemplateRule model) and that is flexible enough to fill in the gaps should one difficulty level not have enough questions to supply the demand at the time of being actually used during a training session, which I’m trying to do with the training session manager). This is slightly harder than anything I’ve done so far with Django.

Thank you for the thorough description, it was quite helpful. (Actually, I’m glad I asked because when I read the original question I had jumped to a completely different conclusion.)

The fundamental answer to your question is that you don’t. Given how Django / Python runs in a production-quality deployment, it’s not practical to update “memory-based” data.

If you want data to be editable, it effectively needs to reside in the database. So what you’re going to want to do is add additional table(s) to store those difficulty profiles in whatever structure you decide is most convenient for you.

1 Like