pythondjangodjango-modelsdjango-ormdjango-migrations

Django Installable App. Abstract class with dependencies on it's implementation


In my installable Django application, I have a class called Timer which I intend for users to implement:

class Timer(models.Model):
  class Meta:
    abstract = True

  project = models.ForeignKey(settings.PROJECT_MODEL)
  user = models.ForeignKey(settings.AUTH_USER_MODEL)

  @abstractmethod
  def finish(self):
    raise NotImplementedError

Additionally, I have a class for recording results:

class TimerResults(models.Model):
  timer1 = models.ForeignKey(settings.TIMER_MODEL)
  parameter1 = models.IntegerField()
  parameter2 = models.IntegerField()
  parameter3 = models.IntegerField()

My plan is for users to create their own Timer, implement finish method, which should then create TimerResults. However, this approach isn't working as intended. When I implement Timer in other app, django try to autodiscover other models, and eventually found TimerResults which has a foreign key referencing settings.TIMER_MODEL. However, TIMER_MODEL is not yet created, resulting in the following error message:

"The field installable_app.TimerResults.timer was declared with a lazy reference to 'app.timer', but app 'app' doesn't provide model 'timer'."

I found a solution where I can make the TimerResults class abstract and force the user to implement it, which solves the problem. However, I'm wondering if there are other ways to solve it.


Solution

  • In conclusion, opting for an abstract class appears to be the most suitable approach for my current situation.

    Alternatively, considering denormalization by storing results as JSON within the Timer model presents itself as a viable solution.

    I also tried using swappable_dependency, but it didn't work because Timer should be already created in initial migration.

    However, it's important to note that implementing an abstract base and a concrete model with a relationship to it seems to be impossible due to these constraints.