2008-11-17 8 views
7

Mam kilka klas modeli z podstawowymi relacjami jeden-do-wielu. Na przykład, książka zawiera wiele przepisów kulinarnych, a każdy przepis ma wiele składników:Spłaszczanie relacji jeden-do-wielu w Django

class Book(models.Model): 
    name = models.CharField(max_length=64) 

class Recipe(models.Model): 
    book = models.ForeignKey(Book) 
    name = models.CharField(max_length=64) 

class Ingredient(models.Model): 
    text = models.CharField(max_length=128) 
    recipe = models.ForeignKey(Recipe) 

Chciałbym płaski wykaz wszystkich składników we wszystkich recepturach z określonej książki. Jaki jest najlepszy sposób wyrażenia tego w Pythonie?

Gdybym był przy użyciu LINQ, mogę napisać coś takiego:

var allIngredients = from recipe in book.Recipes 
        from ingredient in recipe.Ingredients 
        select ingredient; 

Odpowiedz

10

Faktycznie, wygląda na to, że jest to lepsze podejście przy użyciu filtra:

my_book = Book.objects.get(pk=1) 
all_ingredients = Ingredient.objects.filter(recipe__book=my_book) 
+2

Cóż, przypuszczam, że jeśli chcesz to zrobić w prosty, jednoliniowy sposób, możesz to zrobić. ;) –

2

wydrukować każdą recepturę i jego składniki:

mybook = Book.objects.get(name="Jason's Cookbook") 
for recipe in mybook.recipe_set.all(): 
    print recipe.name 
    for ingredient in recipe.ingredients: 
     print ingredient.text 

A jeśli po prostu chcesz uzyskać listę wszystkich obiekty składnika:

mybook = Book.objects.get(name="Jason's Cookbook") 
ingredient_list = [] 
for recipe in mybook.recipe_set.all(): 
    for ingredient in recipe.ingredients: 
     ingredient_list.append(ingredient) 

Documentation.

+0

Hm, nie jestem dokładnie chce wydrukować składniki, ale zbierać je do listy. Wyobrażam sobie, że jest tu prawdopodobnie idiom, którego mi brakuje. –

+0

Zaktualizowałem odpowiedź, o czym myślę, że chcesz. –