我是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
现在,在我的列表视图中,我想将存储的食谱的名称显示为链接。每个菜谱链接都应该调用一个Detail View,该View将显示所选菜谱的配料集。我不知道如何通过外键(指向菜谱)访问它们。
可以通过使用添加_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文档)如果您想减少查询的数量。
假设您希望将HTML模板中存储的食谱名称显示为链接:
views.py
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是应用程序的名称
recipes.html
<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>
ingredients.html
{% for ingredient in ingredients %}
{{ingredient.name}}
{{ingredient.quantity}}
{% endfor %}
urls . py
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'),
]
我想就是这样了,有任何疑问我都乐意解答。