Новичок, использующий django, борется с ListView, но не уверен, почему (menu_list)
Я работаю над своим первым проектом Django (финальный проект для класса Django от codecademy) и делаю веб-страницы для отображения инвентаря и меню ресторана. Я создал модель, представление, шаблон и т.д. для инвентаря, и он отлично отображает ListView. Я сделал то же самое для меню, но оно не работает. Страница загружается, но таблица, которая должна выводить данные, пуста.
Есть идеи, что может идти не так?
PS Я новичок в программировании и это мой первый пост на stackoverflow, так что простите за любые ошибки форматирования или другие промахи
## views.py
from django.http import HttpResponse
from django.shortcuts import render
from .models import Inventory, MenuItem, RecipeRequirement, Purchase
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from django.views.generic import ListView
# Create your views here.
def index(request):
return render(request, "index.html")
class InventoryList(ListView):
template_name = "inventory.html"
model = Inventory
class MenuList(ListView):
template_name = "menu.html"
model = MenuItem
Инвентарь (ниже) работает отлично! :)
{% extends './base.html' %}
{% block content %}
<h2>Inventory</h2>
<table id="inventory">
<tr>
<th>Ingredient</th>
<th>Price</th>
<th>Units Available</th>
</tr>
{% for ingredient in inventory_list %}
<tr>
<tr>
<td>{{ ingredient.ingredient_name }}</td>
<td>{{ ingredient.price }}</td>
<td>{{ ingredient.units_avail }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
Этот (Меню) является проблемным :(
){% extends './base.html' %}
{% block content %}
<h2>Menu</h2>
<table id="menu">
<tr>
<th>Item</th>
<th>Price</th>
<th>In Stock?</th>
</tr>
{% for food in menu_list %}
<tr>
<tr>
<td>{{ food.menu_item_name }}</td>
<td>{{ food.price }}</td>
<td>{{ food.available }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
Модели ниже
from django.db import models
from django.forms import DateTimeField
# Create your models here.
class Inventory(models.Model):
ingredient_name = models.CharField(max_length=30)
price = models.DecimalField(max_digits=5, decimal_places=2)
units_avail = models.IntegerField()
def __str__(self):
return self.ingredient_name + " avail: " + str(self.units_avail)
class MenuItem(models.Model):
menu_item_name = models.CharField(max_length=100)
price = models.DecimalField(max_digits=5, decimal_places=2)
def __str__(self):
return self.menu_item_name + " with Price: " + str(self.price)
def available(self):
return all(recipe_req.enough() for recipe_req in self.reciperequirement_set.all())
class RecipeRequirement(models.Model):
ingredient = models.ForeignKey(Inventory, on_delete=models.CASCADE)
menu_item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
quantity = models.IntegerField()
def __str__(self):
return self.ingredient.ingredient_name + " in " + self.menu_item.menu_item_name
def enough(self):
return self.quantity <= self.ingredient.units_avail
class Purchase(models.Model):
menu_item = models.ForeignKey(MenuItem, on_delete=models.CASCADE)
timestamp = models.DateTimeField()
def __str__(self):
return self.menu_item.menu_item_name + " at " + self.timestamp
URLs below
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("inventory", views.InventoryList.as_view(), name="inventory_list"),
path("menu", views.MenuList.as_view(), name="menu_list"),
]
Я вижу одну проблему, у вас есть один лишний тег <tr>
, открытый в обоих шаблонах чуть ниже цикла.
Также думаю, что есть некоторая проблема с методом available
, который вы вручную определили в модели MenuItem
, поэтому я удалил его, попробуйте без него.
Также я бы рекомендовал вам использовать context_object_name
, который по умолчанию object_list
так:
class InventoryList(ListView):
template_name = "inventory.html"
model = Inventory
context_object_name="inventories"
class MenuList(ListView):
template_name = "menu.html"
model = MenuItem
context_object_name="menu_list"
шаблон inventory.html:
{% extends './base.html' %}
{% block content %}
<h2>Inventory</h2>
<table id="inventory">
<tr>
<th>Ingredient</th>
<th>Price</th>
<th>Units Available</th>
</tr>
{% for ingredient in inventories %}
<tr>
<td>{{ ingredient.ingredient_name }}</td>
<td>{{ ingredient.price }}</td>
<td>{{ ingredient.units_avail }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
шаблон menu.html:
{% extends './base.html' %}
{% block content %}
<h2>Menu</h2>
<table id="menu">
<tr>
<th>Item</th>
<th>Price</th>
<th>In Stock?</th>
</tr>
{% for food in menu_list %}
<tr>
<tr>
<td>{{ food.menu_item_name }}</td>
<td>{{ food.price }}</td>
</tr>
{% endfor %}
</table>
{% endblock %}
Примечание: Рекомендуется давать
/
в конце каждого маршрута, поэтому ваш urls.py должен иметь вид:
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="index"),
path("inventory/", views.InventoryList.as_view(), name="inventory_list"),
path("menu/", views.MenuList.as_view(), name="menu_list"),
]
Примечание: представления на основе классов в Django требуют, чтобы их имя записывалось как имя модели в качестве префикса и фактическое имя представления в качестве суффикса, поэтому вы можете изменить его на
.InventoryListView
иMenuItemListView
сиInventoryList
соответственно.MenuList
Я заметил, что класс модели RecipeRequirement
имеет метод available
. Этот метод вызывает метод enough
из модели класса RecipeRequirement
.
Одной из стратегий устранения неполадок является отключение (закомментирование) методов enough
и available
, поскольку они вводят логику, которая препятствует отображению пунктов меню. Другими словами, ваш код выглядит следующим образом: Если у нас недостаточно ингредиентов, то нет смысла возвращать пункты меню для рецептов, которые мы не можем приготовить.
Альтернативная стратегия устранения неполадок заключается в заполнении таблицы RecipeRequirement
достаточным количеством ингредиентов, и она должна сработать. Предупреждение: этот ответ не проверен.
Вот совет для новичков в кодировании, который хорошо послужил мне на моем коротком пути в разработке программного обеспечения. Ошибки были моим величайшим учителем. Когда есть ошибки, постарайтесь сократить как можно больше элементов. Когда вы натыкаетесь на такую стену, подумайте о том, что необходимо, а остальное закомментируйте. Я предложил сначала закомментировать два метода, потому что они не нужны для отображения таблиц (или для того, что вы считаете главным в своем вопросе). Как только вы добьетесь отображения пунктов меню, вы сможете снова ввести эти методы по одному.