title: jinja2.exceptions.UndefinedError: object has no attribute
body: <p>I am trying to create an Inventory Management System in which i can create/add stock through a form(WTForms) and have it displayed in a table on a separate page. Currently, i am stuck on the stated error. I have looked everywhere for an answer to no avail. I am supposed to add stock through 'createGPU.html' and be directed to 'retrieveGPU.html'</p>
  
  <p>Clicking the submit button in createGPU results in jinja2.exceptions.UndefinedError: 'GPUs.GPUs object' has no attribute 'GPUName'</p>
  
  <p>Main Program</p>
  
  <pre><code>from flask import Flask, render_template, request, redirect, url_for
  from Forms import CreateGPUForm
  import shelve, GPUs
  
  @app.route("/createGPU", methods=['GET', 'POST'])
  def createGPU():
      createGPUForm = CreateGPUForm(request.form)
      if request.method == 'POST' and createGPUForm.validate():
          gpuDict = {}
          db = shelve.open('storage.db', 'c')
  
          try:
              gpuDict = db['GPU']
          except:
              print('Error in retrieving GPUs from storage.db.')
  
          gpu = GPUs.GPUs(createGPUForm.GPUName.data, createGPUForm.GPUUnitPrice.data, createGPUForm.GPUStock.data,createGPUForm.GPUSales.data)
          gpuDict[gpu.get_GPUNo()] = gpu
          db['GPU'] = gpuDict
          db.close()
  
          return redirect(url_for('retrieveGPU'))
      return render_template('createGPU.html', form=createGPUForm)
  
  if __name__ == '__main__':
      app.run()
  
  @app.route('/retrieveGPU')
  def retrieveGPU():
      gpuDict = {}
      db = shelve.open('storage.db', 'r')
      gpuDict = db['GPU']
      db.close()
  
      gpuList = []
      for key in gpuDict:
          gpu = gpuDict.get(key)
          gpuList.append(gpu)
  
      return render_template('retrieveGPU.html',gpuList=gpuList, count=len(gpuList))
  </code></pre>
  
  <p>createGPU</p>
  
  <pre><code>{% extends "base.html" %}
  {% block title %}GPU-Assist - Add Graphics Card{% endblock %}
  
  {% block content %}
  {% from "includes/_formhelper.html" import render_field %}
  
  &lt;h1 class="display-4"&gt;Add Graphics Card&lt;/h1&gt;
    &lt;form method="POST" action=""&gt;
      &lt;div class="form-group"&gt;
        {{ render_field(form.GPUName, class="form-control") }}
      &lt;/div&gt;
      &lt;div class="form-group"&gt;
        {{ render_field(form.GPUStock, class="form-control") }}
      &lt;/div&gt;
      &lt;div class="form-group"&gt;
        {{ render_field(form.GPUUnitPrice, class="form-control")  }}
      &lt;/div&gt;
      &lt;div class="form-group"&gt;
        {{ render_field(form.GPUSales, class="form-control")  }}
      &lt;/div&gt;
      &lt;input type="submit" value="Submit" class="btn btn-primary"/&gt;
    &lt;/form&gt;
  
  
  
  {% endblock %}
  </code></pre>
  
  <p>retrieveGPU</p>
  
  <pre><code>{% extends "base.html" %}
  {% block title %}GPU-Assist - View GPU-Cart{% endblock %}
  
  {% block content %}
  &lt;h1 class="display-4"&gt;View GPU&lt;/h1&gt;
  &lt;div&gt;
    {% if count == 0 %}
    &lt;p&gt;No GPU in recorded in inventory.&lt;/p&gt;
    {% elif count == 1 %}
    &lt;p&gt;There is 1 GPU recorded in the inventory.&lt;/p&gt;
    {% else %}
    &lt;p&gt;There are {{ count }} GPUs recorded in the inventory.&lt;/p&gt;
    {% endif %}
  &lt;/div&gt; &lt;!--End of display number of users div--&gt;
  
  &lt;div&gt;
    &lt;table class="table table-striped"&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th&gt;Name&lt;/th&gt;
          &lt;th&gt;Stock&lt;/th&gt;
          &lt;th&gt;Unit Price&lt;/th&gt;
          &lt;th&gt;Sales&lt;/th&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
         {% for gpu in gpuList %}
        &lt;tr&gt;
          &lt;td&gt;{{ gpu.GPUName() }}&lt;/td&gt;
          &lt;td&gt;{{ gpu.GPUStock() }}&lt;/td&gt;
          &lt;td&gt;{{ gpu.GPUUnitPrice() }}&lt;/td&gt;
          &lt;td&gt;{{ gpu.GPUSales() }}&lt;/td&gt;
          &lt;td&gt;&lt;a href="/updateGPU/{{gpu.get_GPUNo()}}" class="btn btn-warning"&gt;Update&lt;/a&gt;&lt;/td&gt;
          &lt;td&gt;
            &lt;form action="" method="POST"&gt;
              &lt;input type="submit" value="Delete" class="btn btn-danger"&gt;
            &lt;/form&gt;
          &lt;/td&gt;
        &lt;/tr&gt;
      {% endfor %}
  
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
  {% endblock %}
  </code></pre>
  
  <p>GPUs.py</p>
  
  <pre><code>class GPUs:
      countID = 0
      def __init__(self,GPUName,GPUStock,GPUUnitPrice,GPUSales):
          GPUs.countID += 1
          self.__GPUName = GPUName
          self.__GPUStock = GPUStock
          self.__GPUUnitPrice = GPUUnitPrice
          self.__GPUSales = GPUSales
          self.__GPUNo=GPUs.countID
  
  
      '''
      One obvious limitation it has is that every time you restart the web application, the countID resets to 0. 
      Once the countID resets, the next newly created Users’s userID will start from 1 again and overwrite any User 
      that previously had __userID = 1.  (Must figure out an alternative)
      '''
      #Getter or Accessor
      def get_GPUNo(self):
          return self.__GPUNo
      def get_GPUName(self):
          return self.__GPUName
      def get_GPUStock(self):
          return self.__GPUStock
      def get_GPUUnitPrice(self):
          return self.__GPUUnitPrice
      def get_GPUSales(self):
          return self.__GPUSales
  
      #Settor or Mutator
      def set_GPUNo(self, GPUNo):
          self.__GPUNo = GPUNo
      def set_GPUName(self, GPUName):
          self.__GPUName = GPUName
      def set_GPUStock(self, GPUStock):
          self.__GPUStock = GPUStock
      def set_GPUUnitPrice(self, GPUUnitPrice):
          self.__GPUUnitPrice = GPUUnitPrice
      def set_GPUSales(self, GPUSales):
          self.__GPUSales = GPUSales
  
  
  </code></pre>