Creating a primary key for my template to activate the view

My restaurant page has a menu add page where I add a menu item to the list of menu items. Now when I made this page my tutor told me that it would be wise to utilize this code but we created menu items utilizing the admin page. Fast forward a few months where I am on my own and I am trying to click the hyperlink and it will not load. I am getting a no reverse error message because django says that form_tempalte.html cannot find an objects primary key. I say okay, well than all I need to do is create an instance of the class and Django will produce a primary key automatically and my code will work because there will be a primary key and I can at the very least see the menu add page.

What did I try and what am I expecting?
However when I try to create an instance of the menu add like so

class MenuAdditionView(CreateView):
    model = MenuItem
    template_name = "inventory/form_template.html"
    form_class = MenuAdditionForm
    # fields = ["name", "description", "price"]

mongo_db_energy_drink = MenuAdditionView()

I get this error message.

Error Message:
ImportError: attempted relative import with no known parent package
(project_env) andrewstribling@Andrews-MBP djangodelights % 

So I asked Chat GPT and it explained to me that creating objects outside of view functions does not work in Django. (Darn) It says that I need to create an instance of it within a Django view function, which is then linked to a specific url pattern.

example given:

# views.py
from django.views.generic.edit import CreateView
from .forms import MenuAdditionForm
from .models import MenuItem

class MenuAdditionView(CreateView):
    model = MenuItem
    form_class = MenuAdditionForm
    template_name = "inventory/form_template.html"
    success_url = "/menu/"  # or use reverse_lazy here

chat gpt urls.py file

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    # Other URL patterns...
    path('menu/add/', views.MenuAdditionView.as_view(), name="menuadd"),
    # Other URL patterns...
]

my urls.py file

# urls.py 
from django.contrib import admin
from django.urls import path, include
# from inventory.views import finance, home, IngredientsView, MenuView, PurchaseView
from inventory import views # with every view imported you need to specify views.viewname as seen in this file in the code below
from django.views.generic.base import TemplateView
from django.http import HttpResponse

urlpatterns = [
    
    path('', views.home, name='default'), # users don't need to see the rocket page anyway. they need to see the home page.
    path('admin/', admin.site.urls),
    path('finance/', views.finance, name='finance'),
    path('home/', views.home, name='home'), #I am attempting to connect the home_view function with the views function.
    path('ingredients/', views.IngredientsView.as_view(), name='ingredients'),
    path('menu/', views.MenuView.as_view(), name='menu'),
    path('purchases/', views.PurchaseView.as_view(), name='purchases'), 
    path('menu/add/',views.MenuAdditionView.as_view(success_url = "/menu/"), name="menuadd"),
    path('ingredients/add/', views.IngredientAdditionView.as_view(success_url = "/ingredients/"), name='ingredientadd'), # if class based view it requires an as_view
    path('ingredient/update/<int:pk>', views.UpdateIngredientView.as_view(success_url = "/ingredients/"), name='ingredientupdate'),
    path('recipe/add/', views.RecipeRequirementAdditionView.as_view(success_url = "/menu/"), name='recipeadd'),
    path('purchases/add/', views.PurchaseAdditionView.as_view(success_url = "/purchases/"), name = 'purchaseadd'),
    path('update/inventory/<int:pk>/', views.IngredientsListUpdateView.as_view(), name='updateinventory'), # update view so the view had to be edited.}
    # cannot have conflicting path names or matching names
    # finance is not a classed based view therefore i do not need an as_view
    # error message views.finance() type error means I a. calling the fucntion wrong or I am not supposed to be calling it.
    # It needs to know what it is updating. 
    ]

But the error persists it reads:

Traceback:

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/menu/add/

Django Version: 4.2.6
Python Version: 3.11.5
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'inventory.apps.InventoryConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template /Users/andrewstribling/dev/djangodelights/inventory/templates/inventory/form_template.html, error at line 8
   Reverse for 'ingredientupdate' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['ingredient/update/(?P<pk>[0-9]+)\\Z']
   1 : {% extends "inventory/base.html" %}
   2 : {% block content %}
   3 : <form method="POST">
   4 :   {% csrf_token %}
   5 :   {{ form.as_p }}
   6 :   <input type="submit" value="Submit"/>
   7 : </form>
   8 :  {% url 'ingredientupdate' pk=object.pk%} 
   9 : {% endblock %}
   10 : 

Traceback (most recent call last):
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/core/handlers/base.py", line 220, in _get_response
    response = response.render()
               ^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/response.py", line 114, in render
    self.content = self.rendered_content
                   ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/response.py", line 92, in rendered_content
    return template.render(context, self._request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 175, in render
    return self._render(context)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/loader_tags.py", line 157, in render
    return compiled_parent._render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/loader_tags.py", line 63, in render
    result = block.nodelist.render(context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/defaulttags.py", line 471, in render
    url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/urls/base.py", line 88, in reverse
    return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/urls/resolvers.py", line 828, in _reverse_with_prefix
    raise NoReverseMatch(msg)
    ^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: NoReverseMatch at /menu/add/
Exception Value: Reverse for 'ingredientupdate' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['ingredient/update/(?P<pk>[0-9]+)\\Z']

My question is, how do I create an instance so that a primary key can be created and I can move on with my project? I want to create menu object but it seems that this code is creating an ingredient object. How can I get a menu object created?

In here instead of object.pk use object.id, as id the primary key for any instance that Django by default provides.

for some reason the error persists :frowning:

error message

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/menu/add/

Django Version: 4.2.6
Python Version: 3.11.5
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'inventory.apps.InventoryConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template /Users/andrewstribling/dev/djangodelights/inventory/templates/inventory/form_template.html, error at line 8
   Reverse for 'ingredientupdate' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['ingredient/update/(?P<pk>[0-9]+)\\Z']
   1 : {% extends "inventory/base.html" %}
   2 : {% block content %}
   3 : <form method="POST">
   4 :   {% csrf_token %}
   5 :   {{ form.as_p }}
   6 :   <input type="submit" value="Submit"/>
   7 : </form>
   8 :  {% url 'ingredientupdate' pk=object.id%} 
   9 : {% endblock %}
   10 : 

Traceback (most recent call last):
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/core/handlers/base.py", line 220, in _get_response
    response = response.render()
               ^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/response.py", line 114, in render
    self.content = self.rendered_content
                   ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/response.py", line 92, in rendered_content
    return template.render(context, self._request)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/backends/django.py", line 61, in render
    return self.template.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 175, in render
    return self._render(context)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/loader_tags.py", line 157, in render
    return compiled_parent._render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 167, in _render
    return self.nodelist.render(context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/loader_tags.py", line 63, in render
    result = block.nodelist.render(context)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in render
    return SafeString("".join([node.render_annotated(context) for node in self]))
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 1005, in <listcomp>
    return SafeString("".join([node.render_annotated(context) for node in self]))
                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/base.py", line 966, in render_annotated
    return self.render(context)
           ^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/template/defaulttags.py", line 471, in render
    url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/urls/base.py", line 88, in reverse
    return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/andrewstribling/dev/djangodelights/project_env/lib/python3.11/site-packages/django/urls/resolvers.py", line 828, in _reverse_with_prefix
    raise NoReverseMatch(msg)
    ^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: NoReverseMatch at /menu/add/
Exception Value: Reverse for 'ingredientupdate' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['ingredient/update/(?P<pk>[0-9]+)\\Z']



You are using CreateView and there is no object that is passed to your template

So in here from where you are getting object in order to pass it to pk=object.id.
Remove this line for once and then try. Also if you want to update some instance the you have to first create it.

1 Like

Your solution worked!

I am trying to understand how though. Basically by commenting out those lines there no longer needs to be a pk.

So createview created a menu item object. Because createview creates objects.

Yes, correct.
If you need to pass some object to your template via this CreateView then you can override this get_context_data method and then can pass any object that is required.

class MenuAdditionView(CreateView):
    ....

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        return context

my ingredients pages urls have stopped working. I wonder if they are dependent on that line of commented code…

Using the URLconf defined in djangodelights.urls, Django tried these URL patterns, in this order:

[name='default']
admin/
finance/ [name='finance']
home/ [name='home']
ingredients/ [name='ingredients']
menu/ [name='menu']
purchases/ [name='purchases']
menu/add/ [name='menuadd']
ingredients/add/ [name='ingredientadd']
ingredient/update/<int:pk> [name='ingredientupdate']
recipe/add/ [name='recipeadd']
purchases/add/ [name='purchaseadd']
update/inventory/<int:pk>/ [name='updateinventory']
The current path, ingredients/“/ingredient/update/3”, didn’t match any of these.

views.py

from django.shortcuts import render
from django.urls import path, reverse_lazy
from .models import Ingredient, MenuItem, Purchases, RecipeRequirement
from django.views.generic import ListView
from django.core.exceptions import ImproperlyConfigured
# import one at the time write the view for it hook it up in urls.py check if it works than move on to the next one.
from .forms import (
    MenuAdditionForm,
    IngredientAdditionForm,
    UpdateIngredientForm,
    RecipeAdditionForm,
)  # link the views and forms togather on this line

# errors can come from importing on the wrong django.views
from django.views.generic.edit import CreateView, UpdateView
from django.http import HttpResponse

# Create your views here.


def finance(request):
    purchased_items = (
        Purchases.objects.all()
    )  # this grabs every row in the purchases table

    total_revenue = 0
    for item in purchased_items:
        total_revenue = (
            total_revenue + item.menu_order.price
        )  # this uses the price of each item to calculate the revenue

    print(str(total_revenue))
    total_cost = ingredient_cost_calculate()
    print(str(total_cost) + " this is the total cost calculation")

    total_profit = total_revenue - total_cost
    print(str(total_profit) + "total profit calculation amount")

    return render(
        request,
        "inventory/finance.html",
        {
            "total_revenue": total_revenue,
            "total_cost": total_cost,
            "total_profit": total_profit,
        },
    )
    # i want the price of the item and the cost of each item.
    # what holds this information? my ingredient model.
    # it holds the price per unit and the unit.


def ingredient_cost_calculate():
    # classes do not store information objects do.
    # i need the cost per ingredient multiplied by quantity used.
    # I need to than for loop over all of the ingredients in a recipe and than apply the cost per ingredient function or
    # the same mathematical operation.
    # classes do not have the data, the objects do.
    # when the customer purchases something an entry is made in the purchases table.
    # Purchases.objects.all() grabs all of the Purchases data and puts it in a list.
    purchases_objects = Purchases.objects.all()
    # I need to find all of the ingredients per order. How do I get one order to find the ingredients on.
    # I need to use a for loop to access each purchase.
    menu_order_cost = 0
    for purchase in purchases_objects:
        menu_item_object = purchase.menu_order
        # recipe requirements is a list of data
        recipe_requirements = RecipeRequirement.objects.filter(recipe=menu_item_object)
        # we iterate over that list with a for loop and access the iteration variable quantity fields.

        for requirement in recipe_requirements:
            cost_per_ingredient = (
                requirement.quantity * requirement.ingredient.price_per_unit
            )
            menu_order_cost = menu_order_cost + cost_per_ingredient
    return menu_order_cost

    # the purchases are listed by names they do hold the ingredient data for each indvidual order.


def home(request):
    return render(request, "inventory/home.html")


class MenuView(ListView):
    # when we specify the model being used for the template its almost as if we import or give access
    # to the html template the class data for us to use for loops and django code on.
    model = MenuItem
    template_name = "inventory/menu.html"


class PurchaseView(ListView):
    model = Purchases
    template_name = "inventory/purchases.html"


class IngredientsView(ListView):
    model = Ingredient
    template_name = "inventory/ingredients.html"


class IngredientsListUpdateView(ListView):
    model = Ingredient
    template_name = "inventory/ingredients_update.html"


class MenuAdditionView(CreateView):
    model = MenuItem
    template_name = "inventory/form_template.html"
    form_class = MenuAdditionForm
    success_url = "/menu/"
    
    # fields = ["name", "description", "price"]

class IngredientAdditionView(CreateView):
    model = Ingredient
    template_name = "inventory/form_template.html"
    form_class = IngredientAdditionForm


class UpdateIngredientView(UpdateView):  # I am thinking this is an UpdateView
    model = Ingredient
    template_name = "inventory/form_template.html"
    fields = ["quantity", "price_per_unit"]

    # success_url field attribute and reverse_lazy are used with updateview. upon successful completion of the viewd django
    # will route the user to the url with the name pattern of ingredientupdate

    def get_success_url(self):
        """Return the URL to redirect to after processing a valid form."""
        if not self.success_url:
            raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
        return str(self.success_url)  # success_url may be lazy  

    # fields = we need to input the fields of the columns that the provided model has.
    # per ken I need the get_success_url method.


class RecipeRequirementAdditionView(CreateView):
    model = RecipeRequirement
    template_name = "inventory/form_template.html"
    fields = ["ingredient", "recipe", "quantity"]


class PurchaseAdditionView(CreateView):
    model = Purchases
    template_name = "inventory/form_template.html"
    fields = ["menu_order", "timestamp"]


# update view will require a <pk> or slug where I specify what I need to update.
# check out the codecademy section.
# https://www.codecademy.com/paths/build-python-web-apps-with-django/tracks/views-in-django/modules/django-writing-more-views/lessons/django-views/exercises/using-primary-keys-in-urls


# create a view based on the forms made.
# create a path to urls.py

I am having trouble understanding what exactly is going on here.

Starting from urls.py I have different pages on my website with hyperlinks.

These urls have views that that contain the logic to implement view funciton logic. And those views require a template to load.

My hyperlink was not working because of a line of code in my template that said I needed to have a primary key be referenced in a url tag.

After commenting the code out, the requirement for that stopped. It just loaded the template as is and the code worked for that hyperlink I can now create menu items which is good.

A new problem has popped up. My ingredients page hyperlink works but when I click on the indivdidual ingredients they do not work. It says the following error message

Page not found (404)
Request Method:	GET
Request URL:	http://127.0.0.1:8000/ingredients/%E2%80%9C/ingredient/update/3%E2%80%9D
Using the URLconf defined in djangodelights.urls, Django tried these URL patterns, in this order:

[name='default']
admin/
finance/ [name='finance']
home/ [name='home']
ingredients/ [name='ingredients']
menu/ [name='menu']
purchases/ [name='purchases']
menu/add/ [name='menuadd']
ingredients/add/ [name='ingredientadd']
ingredient/update/<int:pk> [name='ingredientupdate']
recipe/add/ [name='recipeadd']
purchases/add/ [name='purchaseadd']
update/inventory/<int:pk>/ [name='updateinventory']
The current path, ingredients/“/ingredient/update/3”, didn’t match any of these.

ingredients hyperlink error

# urls.py 
from django.contrib import admin
from django.urls import path, include
# from inventory.views import finance, home, IngredientsView, MenuView, PurchaseView
from inventory import views # with every view imported you need to specify views.viewname as seen in this file in the code below
from django.views.generic.base import TemplateView
from django.http import HttpResponse

urlpatterns = [
    
    path('', views.home, name='default'), # users don't need to see the rocket page anyway. they need to see the home page.
    path('admin/', admin.site.urls),
    path('finance/', views.finance, name='finance'),
    path('home/', views.home, name='home'), #I am attempting to connect the home_view function with the views function.
    path('ingredients/', views.IngredientsView.as_view(), name='ingredients'),
    path('menu/', views.MenuView.as_view(), name='menu'),
    path('purchases/', views.PurchaseView.as_view(), name='purchases'), 
    path('menu/add/',views.MenuAdditionView.as_view(success_url = "/menu/"), name="menuadd"),
    path('ingredients/add/', views.IngredientAdditionView.as_view(success_url = "/ingredients/"), name='ingredientadd'), # if class based view it requires an as_view
    path('ingredient/update/<int:pk>', views.UpdateIngredientView.as_view(success_url = "/ingredients/"), name='ingredientupdate'),
    path('recipe/add/', views.RecipeRequirementAdditionView.as_view(success_url = "/menu/"), name='recipeadd'),
    path('purchases/add/', views.PurchaseAdditionView.as_view(success_url = "/purchases/"), name = 'purchaseadd'),
    path('update/inventory/<int:pk>/', views.IngredientsListUpdateView.as_view(), name='updateinventory'), # update view so the view had to be edited.}
    # cannot have conflicting path names or matching names
    # finance is not a classed based view therefore i do not need an as_view
    # error message views.finance() type error means I a. calling the fucntion wrong or I am not supposed to be calling it.
    # It needs to know what it is updating. 
    ]

Looking at the urls pathway ingredient update is called when I click on the ingredients hyperlink. that ingredient update requires update ingredient view as the model that I need to be looking at.

and it…

aww crud…

It uses inventory/form_template.html and uses that line of code.

Okay so my problem solving skills say maybe I should create a clone of this template, rename it, uncomment that line of code there and than fix my url path for ingredient update to go to the clone.

What do you think?

I suppose I could try it. attempting…

Let’s clear things out.

First you have this url path which allows you to create a ingredient which will render a form using IngredientAdditionView where you have passed the IngredientForm.
Now there might be a create_template.html which you are using only for addition functinality.

Now comes the part for this url which is for updating a ingredient, now for this you might be using different update_template.html where you are passing a ingredient object to the template in order to update that particular instance.

by clear things out do you mean re evaluate what my templates are doing and make sure I have not created another one?

Ingredient AdditionView

class IngredientAdditionView(CreateView):
model = Ingredient
template_name = “inventory/form_template.html”
form_class = IngredientAdditionForm

class UpdateIngredientView(UpdateView): # I am thinking this is an UpdateView
model = Ingredient
template_name = “inventory/form_template.html”
fields = [“quantity”, “price_per_unit”]

crud. it seems that I have different views depending on the same template.

But UpdateView demands a primary key where as CreateView does not. If I comment out the code other pages work, but I see an error in my ingredients page. If do not comment it out my updateview will work but my createview pages error out.

So should I create a new template specifically for my udpate view and have the other ones enjoy the one that is not commented out?

OR are you trying to tell me there is another way?

By the way thank you for helping me.

templates being used

base.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div class="topnav">
      <!-- the green text is talking about paths the white is what is on the page-->
      <a href="{% url 'home' %}">Home</a>
      <a href="{% url 'ingredients' %}">Ingredients</a>
      <!-- name= connection-->
      <a href="{% url 'menu' %}">Menu</a>
      <a href="{% url 'finance' %}">Finance</a>
      <a href="{% url 'purchases' %}">Purchases</a>
      <a href="{% url 'menuadd' %}">Add Menu</a>
      <!--utilize name in urls.py -->
      <a href="{% url 'ingredientadd' %}">Add Ingredient</a>
      <a href="{% url 'recipeadd' %}">Add Receipe</a>
      <a href="{% url 'purchaseadd' %}">Add Purchase</a>
      {# <a href="{% url 'ingredientupdate' object.pk %}">Ingredient Update</a> #}
    </div>

    {% block content %} {% endblock %}
  </body>
</html>

ingredients_update.html

{% extends 'inventory/base.html' %} 

{% block content %}
{% load static %}
<link rel = "stylesheet" href="{% static 'inventory/style.css' %}">
<h1> Welcome to the ingredients page!</h1>

<table>
    <thead>
        <tr>
            <th>Ingredient Name</th>
            <th>Quantity</th>
            <th>Unit Type</th>
            <th>Price Per Unit</th>
            <th></th>
        </tr>
    </thead>
    {% for item in object_list %}
    <tr><td>{{ item.name }}</td> 
        <td>{{ item.quantity}}</td> 
        <td>{{ item.unit }}</td> 
        <td>{{ item.price_per_unit }}</td>
        <td><a href="/update/inventory/{{ item.pk }}"><button>Link</button></a></td> <!-- this is what we add to the page that is not copied from ingredients.-->
    </tr>
    {% endfor %}
</table>
{% endblock %}

ingredients.html

{% extends 'inventory/base.html' %} 

{% block content %}
{% load static %}
<link rel = "stylesheet" href="{% static 'inventory/style.css' %}">
<h1> Welcome to the ingredients page!</h1>

<table>
    <thead>
        <tr>
            <th>Ingredient Name</th>
            <th>Quantity</th>
            <th>Unit Type</th>
            <th>Price Per Unit</th>
        </tr>
    </thead>
    <!-- context is a list of objects from a listview 
    object list is is inside of context and its a list of items.
    this for loop says itemize each item in object list and iterates over item.name
    the model that listview is using has attributes such as item.name and so on. 

    listview has a built in system to query the database for the model specified


    model specifies what data exists in the database 
    there are views of different types and they views take data from the model in their respective different ways.
    in other words the view decides what is taken from the database and what functions it can operate with.
    context is the mechanism that the view uses to talk to the template. 
    The template can only grab things from the context. the view CANNOT talk to the model.--> 
    {% for item in object_list %}
    <tr><td>
        {{ item.name }} 
        <a target=“_blank” href=“{% url "ingredientupdate" item.pk %}”>{{ item.name }}</a>
        </td> 
        <td>{{ item.quantity}}</td> 
        <td>{{ item.unit }}</td> 
        <td>{{ item.price_per_unit }}</td>
    </tr>
    {% endfor %}
</table>
{% endblock %}

curses!!! my plan failed?

I updated my UpdateIngredientView template_name attribute to my clone and than it uncommented the ingredient update line url and the error persists. I do not know why for it worked under the old format.

I will keep working…

Per the error message

Using the URLconf defined in djangodelights.urls, Django tried these URL patterns, in this order:

  1. [name=‘default’]
  2. admin/
  3. finance/ [name=‘finance’]
  4. home/ [name=‘home’]
  5. ingredients/ [name=‘ingredients’]
  6. menu/ [name=‘menu’]
  7. purchases/ [name=‘purchases’]
  8. menu/add/ [name=‘menuadd’]
  9. ingredients/add/ [name=‘ingredientadd’]
  10. ingredient/update/int:pk [name=‘ingredientupdate’]
  11. recipe/add/ [name=‘recipeadd’]
  12. purchases/add/ [name=‘purchaseadd’]
  13. update/inventory/int:pk/ [name=‘updateinventory’]

The current path, ingredients/“/ingredient/update/3”, didn’t match any of these.

The thing is I never told it to go ingreidents/ingredient update.

Still working on it…