Hello everyone,
As the title indicates, I try to inherit two properties of a class in all of my model classes.
So I have a classic python class in my project application like this with two properties that customize Django’s save() function to differentiate save of forms and save of model objects. This allows me to automatically increment a historical table to each save in my scripts.
app1/custom_methods.py
from django import forms
from history.functions import * #some basic functions to save a new object in my history table
class custom_save(forms.BaseModelForm): #use BaseModelForm to call django's save()
def save_form(self, user, commit=True):
#part to generate dictionnary with attributes and values of object before change
try:
previousObj = self._meta.model.objects.get(pk=self.instance.pk)
previousObjDic={self._meta.model._meta.get_field(att).verbose_name : getattr(previousObj, att) for att in self._meta.fields}
except:
previousObj = None
previousObjDic={self._meta.model._meta.get_field(att).verbose_name : None for att in self._meta.fields}
#call common django's save
instanceObj = super().save(commit=False) #form first
if commit : instanceObj.save() #then model object
#part to generate dictionnary with attributes and values of object after change
newObjDic = {self._meta.model._meta.get_field(att).verbose_name : self._meta.model._meta.get_field(att).value_from_object(self.instance) for att in self._meta.fields}
#check for differencies
for att in previousObjDic.keys():
if previousObjDic[att] != newObjDic[att]:
#function from history.functions
SaveInHistory(user,previousObj, att, previousObjDic[att], newObjDic[att])
def save_model(self, user):
#part to generate dictionnary with attributes and values of object before change
previousObj = self
previousObjDic={att.verbose_name:getattr(self,att) for att in self._meta.fields}
#call common django's save
super().save()
#part to generate dictionnary with attributes and values of object after change
newObjDic = {att.verbose_name : getattr(self,att) for att in self._meta.fields}
#check for differencies
for att in previousObjDic.keys():
if previousObjDic[att] != newObjDic[att]:
history_funcs.SaveModificationBis(user, previousObj, att, previousObjDic[att], newObjDic[att])
Then I call this class to inherit these two functions in each Model or Form.
app2/models.py
from django.db import models
from general import custom_methods
class Person(models.Model, custom_methods.custom_save):
first_name = models.CharField{max_length = 50, blank = True}
last_name = models.CharField{max_length = 50, blank = True}
age = models.IntegerField{default = 0}
app3/forms.py
from django import forms
from general import custom_methods
from app2.models import Person
class PersonForm(forms.ModelForm, custom_methods.custom_save) :
class Meta :
model = Person
fields = (
'first_name',
'last_name',
'age'
)
widgets = {
'first_name' : forms.TextInput(attrs= {'class': 'form-control'}),
'last_name' : forms.TextInput(attrs= {'class': 'form-control'}),
'age': forms.NumberInput(attrs= {'class': 'form-control'})
}
And finally in the view I call my backup properties.
app2/views.py
[...]
newObject = Person(
first_name = 'Sherlock',
last_name= 'Holmes',
age= 52,
)
newObject.save_model(request.user)
[...]
Everything works independently, the generation of dictionaries before/after, the detection of modified attributes, their registration in the history table…
But I have a mistake when I try to do allObjects = Person.objects.all() in my view, Django sends me
Error in formatting: RecursionError: maximum recursion depth exceeded while calling a Python object
I know that it comes from the inheritance process because when i remove “custom_methods.custom_save” from the Person model’s attributs the script is working.
I also tried with a form saving in view and it’s working perfectly.
So i don’t know, I don’t see any conflict in names that could cause recursion. And I don’t understand why the error concerns this line where i don’t use my custom properties.
Also I suspect my method may not be the best to generate a history so if you have any advice to improve it I’m a taker.
Thank you in advance for your help