Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circular import issues with Django apps that have dependencies on each other

I am writing a couple of django apps which by design are coupled together. But I get circular import problems. I know it might be bad design, so please give examples of better solutions. I can't seem to find a better suited design, so if there isn't a better design, how to solve this one?

It is basically two django apps, with some models, which relate to each other cross app-wise. In short the system is an event based system. So there is an event model and a task model. These live in two different apps, Events and Tasks. When events is triggered, I need to check that certain tasks are solved or not, and when a task is solved, that can trigger some other events.

So in Events I need to store data about tasks (to check if these tasks are solved) and in Tasks I need to store data about events (which events to trigger when they are solved)

Here is some sample code from my apps:

Events app
models.py

from tasks.models import Task

class Event(models.Model):
    ...
    tasks = models.ManyToManyField(Task, help_text=_("Tasks we need to check if are solved before triggering this event."))
    ...


Tasks app
models.py

from events.models import Event

class Task(models.Model):
    ...
    events = models.ManyToManyField(Event, help_text=_("Events to trigger when this task i solved."))
    ...

This is causing import problems when I try to validate:

AttributeError: 'module' object has no attribute 'Event'

So how to solve this? Ive tried to use some of the django helper functions in hope that that would help, more specifically I've tried to use the django.db.models.get_app and get_model functions to import the models instead of directly importing them, but I still get problems.

Of course I could collect them into the same app, but I clearly believe they should live in separate apps, since they handle separate things. But yes they are dependent on each other. If I can't solve the import problems, any ideas on how to design this different?

I could of course use some generic relations, but that would actually make things harder to understand for other people since it doesn't specify the content type that it should relate to.

like image 964
espenhogbakk Avatar asked Mar 09 '10 22:03

espenhogbakk


1 Answers

Both models do not need many-to-many fields.

Do not put both sides of a many-to-many relationship in your model.

When you put in one many-to-many relationship, Django inserts the other side of the relationship for you.

http://docs.djangoproject.com/en/1.1/topics/db/queries/#many-to-many-relationships

Both ends of a many-to-many relationship get automatic API access to the other end. The API works just as a "backward" one-to-many relationship, above.

"When events is triggered, i need to check that surtain tasks are solved or not".

  • This means that Event can be triggered some other way and is independent of any Task.

  • If an Event can be triggered and that leads to Tasks, then Tasks depend on Events.

"when a task is solved, that can trigger some other events"

  • This means that Tasks depend on Events. Events do not depend on Tasks.

Put the many-to-many reference to Events in Tasks. Put nothing in Events, since Events can be used elsewhere, to trigger a chain of Tasks and other Events. Some client application will import Events only.

Further, you can provide many-to-many field references using a string name instead of importing the model.

like image 164
S.Lott Avatar answered Sep 30 '22 06:09

S.Lott