Ma solution:
oui. Une solution simple et rapide je suivais comme suit: Je crée trois modèles similaires à ceci:
class my_super_abstract_model(Model):
#All fields I need to keep a history for:
fieldA = models.FloatField()
fieldB = models.FloatField()
class Meta:
abstract = True
class my_model(my_super_abstract_model):
def has_history(self):
return self.my_model_history_set.count() > 0
class my_model_history(my_super_abstract_model):
reason = models.TextField()
history_entry_for = models.ForeignKey(my_model)
J'ai installé un signal:
pre_save.connect(create_history,
sender = my_model_history)
et « créer l'histoire » à appeler par le signal pre_save() avant d'enregistrer en my_model_history:
def create_history(sender, **kwargs):
#get variables passed by the pre-save signal:
history_model = kwargs['instance']
# Get main model object
main_model = history_model.history_entry_for
# swap all common fields between history edit and main model (except id)
main_model_fields = [f.name for f in main_model._meta.fields]
history_model_fields = [f.name for f in history_model._meta.fields]
field_index = list([f for f in history_model_fields if f in main_model_fields and f != 'id' and f != 'created_date' ])
#loop thru to swap values:
for field_name in field_index:
temp = getattr(main_model, field_name)
setattr(main_model, field_name, getattr(history_model, field_name))
setattr(history_model, field_name, temp)
# After the swap, save main model object here
main_model.save()
Chaque fois que l'utilisateur clique sur une ligne de my_model pour l'édition, j'utilise « my_model_history » pour générer ma forme d'édition et remplissez-le avec les valeurs de la ligne sélectionnée par l'utilisateur. (Ont écrit une vue et un modèle pour le faire)
Ainsi, le formulaire d'édition aura maintenant:
champ
- A -populated avec des valeurs de données my_model ligne
champ
- B -populated avec des valeurs de données my_model ligne
- Raison zone de texte -empty
- history_entry_for -hidden de la vue
L'utilisateur peut maintenant modifier champA/champB. Entrez une raison. Appuyez sur Enregistrer pour déclencher le signal ci-dessus. Avant d'enregistrer,
- Signal échangera les valeurs entre le modèle principal (anciennes valeurs) et modèle d'histoire (nouvelles valeurs)
- Remplacer et enregistrer la ligne principale du modèle (avec les nouvelles valeurs).
- Insérez et enregistrez une nouvelle ligne dans le modèle d'historique (avec les anciennes valeurs) avec une raison.
Espérons que cela aide. Faites-moi savoir s'il y a d'autres questions.
Je ne sais pas si cela vous convient, mais django-reversion (https://github.com/etianen/django-reversion) est une solution très pratique pour administrer l'histoire d'un modèle! –
Hmm c'est une bonne extension, mais c'est plus d'aider dans le développement et de fournir beaucoup d'autres fonctionnalités qui n'ont rien à voir avec mes besoins. Mettre en œuvre ceci pourrait être exagéré pour ce dont j'ai besoin. – sysasa
Avez-vous déjà choisi une solution? –