[英]Django templates: data filtering by foreign key
我是 Django 的新手,我有一個似乎無法解決的問題。 長話短說,我創建了一個基於文本的應用程序,可以幫助我制定膳食計划並生成購物清單。 我正在嘗試用 django 重新創建。
這是我的模型:
class Recipe(models.Model):
name = models.CharField(max_length=40)
def __str__(self):
return self.name
class Category(models.Model):
name = models.CharField(max_length=20)
def __str__(self):
return self.name
class Ingredient(models.Model):
name = models.CharField(max_length=20)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
def __str__(self):
return self.name
class IngredientSet(models.Model):
recipe = models.ForeignKey(Recipe, on_delete=models.SET_NULL, null=True)
ingredient = models.ForeignKey(Ingredient, on_delete=models.DO_NOTHING)
quantity = models.FloatField()
def __str__(self):
return self.ingredient.name
現在,在我的列表視圖中,我想將存儲的食譜的名稱顯示為鏈接。 每個配方鏈接都應調用一個詳細視圖,該視圖將顯示所選配方的成分集。 我不知道如何通過他們的外鍵(指向一個食譜)來訪問它們。
可以使用小寫的 model 名稱並附加_set
來訪問反向關系。 對於Recipe
和IngredientSet
集,您可以編寫recipe.ingredientset_set.all()
來獲取與食譜相關的所有IngredientSet
集實例。 可以通過設置related_name
名稱來自定義此名稱,例如:
class IngredientSet(models.Model):
recipe = models.ForeignKey(Recipe, on_delete=models.SET_NULL, null=True, related_name="ingredient_sets")
ingredient = models.ForeignKey(Ingredient, on_delete=models.DO_NOTHING)
quantity = models.FloatField()
def __str__(self):
return self.ingredient.name
現在你可以編寫recipe.ingredient_sets.all()
。
要在模板中循環這個,可以簡單地寫:
{% for ingredient_set in recipe.ingredient_sets.all %}
{{ ingredient_set.ingredient.name }}
{{ ingredient_set.quantity }}
{% endfor %}
注意:這將對每個配方的數據庫進行查詢以獲取其成分集。 如果你想減少查詢的數量,你可以使用
prefetch_related
[Django docs] 。
假設您要將 html 模板中存儲的配方名稱顯示為鏈接:
from .models import Recipe, Ingredient, IngredientSet
from django.shortcuts import render
def recipes(request):
recipes_for_template = Recipe.objects.all()
return render(request, 'main/recipes.html', {"recipes": recipes_for_template})
def ingredients(request, cod_recipe):
ingredients_sets = IngredientSet.objects.filter(recipe=cod_recipe)
ingredients_to_template = []
for ingredient_set in ingredients_sets:
ingredient_obj = Ingredient.objects.get(id=ingredient_set.id)
dict_of_ingredient = {
"name": ingredient_obj.name,
"quantity": ingredient_set.quantity
}
ingredients_to_template.append(dict_of_ingredient)
return render(request, 'main/ingredients.html', {"ingredients": ingredients_to_template})
其中 main 是應用程序的名稱
<table>
<thead>
<th>Recipe</th>
</thead>
<tbody>
{% for recipe in recipes %}
<tr>
<td>
<a href="./{{recipe.id}}/">{{recipe.id}}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% for ingredient in ingredients %}
{{ingredient.name}}
{{ingredient.quantity}}
{% endfor %}
from django.urls import path
from . import views
app_name = "main"
urlpatterns = [
path('recipe/', views.recipes, name='recipes'),
path('recipe/<int:cod_recipe>/', views.ingredients, name='ingredients'),
]
我想就是這樣,任何疑問我都會很樂意回答。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.