Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django maintain versions of a model object

Tags:

python

django

I have a model Goal which has two M2M fields and is referred to by another model Event. Now, the requirement is such that Goal is editable which means I can add/delete from M2M fields and add/delete events. But editing goes through moderation and only after approval the changes are to be reflected or in case of rejection changes must be reverted.

I have gone through deepcopy but it doesn't serve my purpose because lets say if I do x=deepcopy(goal object) I get copy of goal object but I am unsure what I can do with it.

Then I came to know about model_to_dict from django.forms module it serializes the whole object which is handy. I was thinking may be I could use this dictionary to create a model RevisedGoal with original goal as foreign key. Is it a feasible solution? Are there any othe ways of achieving this?

like image 482
Rajesh Yogeshwar Avatar asked Mar 16 '16 10:03

Rajesh Yogeshwar


People also ask

What is version control in Django?

Django-versioning allows you to version the data stored in django models, and stores only diff, not content copy. Supports all field types excepts ManyToMany (currently). Maybe also useful for your project: the Django built-in comments app and the way of referring to objects.

What is __ str __ In Django model?

The __str__() method is called whenever you call str() on an object. Django uses str(obj) in a number of places. Most notably, to display an object in the Django admin site and as the value inserted into a template when it displays an object.

How Django knows to update VS insert?

The doc says: If the object's primary key attribute is set to a value that evaluates to True (i.e. a value other than None or the empty string), Django executes an UPDATE. If the object's primary key attribute is not set or if the UPDATE didn't update anything, Django executes an INSERT link.

What is Get_absolute_url in Django?

Django documentation says: get_absolute_url() method to tell Django how to calculate the canonical URL for an object.


1 Answers

I think that you're essentially asking how you can keep track of changes to Goal's M2M fields such that they can be approved or reverted. If you need to persist these pending changes to the database to approve or deny later, then cloning the model may not be the best solution, particularly if you want to revert. If you expect a lot of these changes, you'll want to separate the potential changes from the "live" instances of your Goals and Events.

I would suggest creating a new model that is linked to Goal and represents these pending changes. This object would keep track of added/removed records from the Goals M2M fields, and could contain some additional fields related to approval (like who approved the changes and when). When one of these new objects gets marked approved, you can make the requisite changes on the original Goal instance.

How you keep track of the added/removed M2M fields is the tricky part. In the example below, I've just created corresponding M2Ms on the pending changes object that you could iterate through on approval to apply to the original Goal object.

class Goal(models.Model):
...


class PendingGoalChange(models.Model):
    goal = models.ForeignKey(Goal, related_name='changes')
    approved = ...
    approver = ....

    added_m2m_field_instances = models.ManyToMany(...)
    removed_m2m_field_instances = models.ManyToMany(...)

    def approve(self):
        self.approved = True
        ...
        for new_field in self.added_m2m_field_instances.all():
            self.goal.field.add(new_field)
like image 93
Jordan Haines Avatar answered Oct 03 '22 02:10

Jordan Haines