Cannot see foreign key values in the template
This is my 2nd week learning Django. I'm trying to get comfortable with Django Template Language. I'm trying to make an Inventory app with 4 models. The views for them are class-based.
The templates for Ingredient and Menu work as expected. However, I'm struggling with trying to loop through values from the Purchase model which has a foreign key field 'menu_item'. The template is not showing anything from the for loop. I've referred numerous articles here to find most of them use function-based views. I've tried using {% for purchase in purchase_set %}, {% for purchase in purchase_set.all %}. I know the object to iterate over is a query-set. I cannot figure out what to do?
MODELS.PY
from django.db import models
# Create your models here.
class Ingredient(models.Model):
Pounds = 'lbs'
Ounces = 'oz'
Grams = 'gms'
Eggs = 'eggs'
Piece = 'piece'
Litre = 'litre'
unit_choices = [(Pounds, 'lbs'),
(Ounces, 'ounces'),
(Grams, 'grams'),
(Eggs, 'eggs'),
(Piece, 'piece'),
(Litre, 'litre')]
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
unit_price = models.FloatField(default=0.0)
quantity = models.FloatField(default=0.0)
unit = models.CharField(max_length=10, choices=unit_choices)
class Meta:
ordering = ['id']
def __str__(self):
return self.name
class MenuItem(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=50)
price = models.FloatField(default=0.0)
class Meta:
ordering = ['id']
def __str__(self):
return self.title
class RecipeRequirement(models.Model):
menu_item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
quantity = models.FloatField(default=0.0)
def __str__(self):
return self.menu_item.title
class Purchase(models.Model):
menu_item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
timestamp = models.DateTimeField()
id = models.AutoField(primary_key=True)
class Meta:
ordering = ['id']
def __str__(self):
return self.menu_item.title
VIEWS.PY:
from django.shortcuts import render
from .models import Ingredient, MenuItem, RecipeRequirement, Purchase
from django.views.generic import ListView
def home(request):
return render(request, 'inventory/home.html')
class IngredientView(ListView):
model = Ingredient
template_name = 'inventory/ingredients.html'
class PurchaseView(ListView):
model = Purchase
template_name = 'inventory/purchases.html'
class MenuView(ListView):
model = MenuItem
template_name = 'inventory/menu.html'
PURCHASES.HTML
<h3>This is purchases page.</h3>
{% block content %}
<table>
{% for purchase in purchase_set.all %}
<tr>
<td>{{ purchase.title }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
The title
field you are trying to show is in MenuItem
model that is used as foreignkey in Purchase
model with menu_item
field. ListView class returns to context yours purchases in object_list
key. So in Your purchases.html template:
<h3>This is purchases page.</h3>
{% block content %}
<table>
{% for purchase in object_list %}
<tr>
<td>{{ purchase.menu_item.title }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
PS. This `purchase_set' is referring to reverse relationship. So if you would want to show all purchases of MenuItem you would do:
{% for item in menuitems %}
<h1>{{ item }}</h1>
{% for purchase in item.purchase_set.all %}
<p>{{ purchase.timestamp }}</p>
{% endfor %}
{% endfor %}