簡體   English   中英

Django 模板:外鍵數據過濾

[英]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來訪問反向關系。 對於RecipeIngredientSet集,您可以編寫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 模板中存儲的配方名稱顯示為鏈接:

視圖.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 是應用程序的名稱

食譜.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>

成分。html

{% for ingredient in ingredients %}
    {{ingredient.name}}
    {{ingredient.quantity}}
{% endfor %}

網址.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'),
]

我想就是這樣,任何疑問我都會很樂意回答。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM