4

Lets say I want to track employees working on projects.

Project 2015
- Employee A

Employee A now changes his healthcare-provider, address and completes his bachelor degree.

Project 2018
- Employee A

For Project 2018 the Employee A details are up to date. But if I look back at project 2015 the Employee A details are now newer than the Project itself. For example now it looks like Employee A had a bachelors degree when working at Project 2015, which is incorrect. What I need is like an instance of Employee A frozen in time/time capsule/snapshot/copy when saving him to a Project. While still being able to update the "live" version of the employee.

There are other models where I will run into the same problem. It really boggles my mind, because it's so counterintuitive for database-thinking. Is there a right/correct way to handle this. Is there maybe a Django revision? solution? Thank You!

jlplenio
  • 115
  • 1
  • 9

2 Answers2

3

The project django-simple-history is very useful and you can have snapshots of your objects.

Gregory
  • 6,514
  • 4
  • 28
  • 26
1

I had similiar challenges and we worked it out by doing a pattern that would rougly translate to this domain as:

class EmployeeProfile(Model):
    class Meta:
        abstract = True

    common_field1 = CharField()
    common_field2 = CharField()
    common_field3 = CharField()

    def get_employee_profile_data(self):
        return {
            'common_field1': self.common_field1,
            'common_field2': self.common_field2,
            'common_field3': self.common_field3,
        }


class Employee(EmployeeProfile):
    specific_fields


class ProjectProfile(EmployeeProfile):
    class Meta:
        unique_together = ('project', 'employee')

    project = ForeignKey(Project)
    owner = ForeignKey(Employee) # Means that the Employee "owns" this profile


# A factory function
def create_project_profile(employee, project):
    return ProjectProfile.objects.create(
        project=project,
        owner=employee,
        **employee.get_employee_profile_data())

We tried to think with separation of concern in mind.

I this scenario I think the pattern fulfills the following:

  • A project have project specific profile which is owned by an Employee

  • An employee can only have one profile per project

  • It is possible to change the specific profile for a project without affecting the "live data"

  • It is possible to change an employee profile live data without affecting any project

Benefits are that database migrations will affect both Employee and the ProjectProfile and it should be simple to put get_employee_profile_data under unittest. The owner reference will make sure it's easy to query for participants etc for projects.

Hope it can give some ideas...

Daniel Backman
  • 5,121
  • 1
  • 32
  • 37