Frage

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()
War es hilfreich?

Lösung

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)

Andere Tipps

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.

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): ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top