Reputation: 911
I have a project which looks like:
mysite/
|-- books
| |-- __init__.py
| `-- models.py
`-- org
|-- __init__.py
`-- models.py
books/models.py:
from django.db import models
from mysite.org.models import Team
class BookSet(models.Model):
name = models.CharField(max_length=10)
team = models.ForeignKey(Team, related_name='booksets')
class Book(models.Model):
name = models.CharField(max_length=10)
book_set = models.ForeignKey(BookSet, related_name='books')
org/models.py:
from django.db import models
class Department(models.Model):
name = models.CharField(max_length=20)
class Team(models.Model):
name = models.CharField(max_length=20)
department = models.ForeignKey(Department, related_name='teams')
What I want to achieve is getting all books for a Department, something similar to:
class Department(models.Model):
name = models.CharField(max_length=20)
@property
def books(self):
# this won't work, is there any possible do it like this?
return self.teams.booksets.books()
I know one possible method is doing it via:
from mysite.books.models import Book
class Department(models.Model):
name = models.CharField(max_length=20)
@property
def books(self):
return Book.objects.filter(book_set__team__department=self)
But with this method, I need to do something tricky to allow them (books.models and org.models) to import each other cyclically.
So I'm wondering whether it's possible to find out all the Books for a Department by querying with the foreign key, which is something like:
@property
def books(self):
# this won't work, is there any possible do it like this?
return self.teams.booksets.books()
Upvotes: 2
Views: 1946
Reputation: 2165
You could use the same mechanism that Django uses to load Foreign Keys like
user = models.ForeignKey('User')
How do to that:
from django.db.models.loading import get_model
Book = get_model('books', 'Book')
# which would achieve the same thing as
# from books.models import Book
get_model
is defined as:
def get_model(self, app_label, model_name, seed_cache=True):
...
Upvotes: 1
Reputation: 1068
I think something like this would work:
class Department(models.Model):
name = models.CharField(max_length=20)
@property
def books(self):
booksets = list(team.booksets.all() for team in self.teams.all())
return list(bookset.books.all() for bookset in booksets)
But I don't have an easy way to test it.
Edit: An alternative I forgot to add:
You can use strings to refer to models in ForeignKey definitions. like so:
class BookSet(models.Model):
name = models.CharField(max_length=10)
team = models.ForeignKey('org.Team', related_name='booksets')
Then in you're other application you can freely import books.models
See the docs for more info.
Upvotes: 2
Reputation: 23316
An easy way to avoid the cyclical import is by making your your Department
model like so:
class Department(models.Model):
name = models.CharField(max_length=20)
@property
def books(self):
from mysite.books.models import Book
return Book.objects.filter(book_set__team__department=self)
Upvotes: 3