-1

Python version 3.7.7 and Django version 2.2.3. Code on Github https://github.com/jcwill415/Stock_Market_Web_App

I want to add a delete button in the last column of a table. When the code is outside of the table, it works to delete an entry from the table. But when the code is inside the table, I receive a NoReverseMatch error that says:

  NoReverseMatch at /add_stock.html 
  Reverse for 'delete' with arguments '('',)' not found. 1 pattern(s) tried: ['delete/(?P<stock_id>[^/]+)$']

Request Method: GET
Request URL:    http://localhost:8000/add_stock.html
Django Version: 2.2.3
Exception Type: NoReverseMatch
Exception Value:    
Reverse for 'delete' with arguments '('',)' not found. 1 pattern(s) tried: ['delete/(?P<stock_id>[^/]+)$']
Exception Location: C:\djangostock\venv\lib\site-packages\django\urls\resolvers.py in _reverse_with_prefix, line 668
Python Executable:  C:\djangostock\venv\Scripts\python.exe
Python Version: 3.7.7
Python Path:    
['C:\\Users\\JCW\\Desktop\\Stock_Market_Web_App-master\\stock',
 'C:\\Users\\JCW\\AppData\\Local\\Programs\\Python\\Python37-32\\python37.zip',
 'C:\\Users\\JCW\\AppData\\Local\\Programs\\Python\\Python37-32\\Lib',
 'C:\\Users\\JCW\\AppData\\Local\\Programs\\Python\\Python37-32\\DLLs',
 'C:\\Program Files\\Python37',
 'C:\\djangostock\\venv',
 'C:\\djangostock\\venv\\lib\\site-packages']

add_stock.html

<table class="table table-striped table-hover">

  <thead class="thead-dark">
    <tr>
      <th scope="col">TICKER</th>
      <th scope="col">COMPANY</th>
      <th scope="col">STK PRICE</th>
      <th scope="col">PREV CLOSE</th>
      <th scope="col">MARKET CAP</th>
      <th scope="col">VOLUME</th>
      <th scope="col">YTD CHG</th>
      <th scope="col">52 WK HIGH</th>
      <th scope="col">52 WK LOW</th>
      <th scope="col">REMOVE STK</th>
    </tr>
  </thead>
  <tbody>
{% if ticker %}
      
            {% for list_item in output %}
                <tr>
                    <th scope="row">{{ list_item.symbol }}</th>
                    <td>{{ list_item.companyName }}</td>
                    <td>${{ list_item.latestPrice }}</td/>
                    <td>${{ list_item.previousClose }}</td>
                    <td>${{ list_item.marketCap }}</td>
                    <td>{{ list_item.latestVolume }}</td>
                    <td>{{ list_item.ytdChange }}</td>
                    <td>${{ list_item.week52High }}</td>
                    <td>${{ list_item.week52Low }}</td>
                    <td><a href="{% url 'delete' item.id %}" class="btn btn-outline-danger btn-small">Delete {{ item }}</a></br></td>          
        </tr>
        
            {% endfor %}
        
  </tbody>
</table>
{% endif %}

{% for item in ticker %}
    <a href="{% url 'delete' item.id %}" class="btn btn-outline-danger btn-small">Delete {{ item }}</a> &nbsp;
{% endfor %}

views.py

def delete(request, stock_id):
    item = Stock.objects.get(pk=stock_id) # call database by primary key for id #
    item.delete()
    messages.success(request, ("Stock Has Been Deleted From Portfolio!"))
    return redirect('add_stock')

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name="home"),
    path('about.html', views.about, name="about"),
    path('add_stock.html', views.add_stock, name="add_stock"),
    path('delete/<stock_id>', views.delete, name="delete"),
    path('news.html', views.news, name="news"),
    
]

What I've Tried I've tried using a for loop:

{% for item in ticker %}
   <td><a href="{% url 'delete' item.id %}" class="btn btn-outline-danger btn-small">Delete {{ item }}</a></td>
{% endfor %}

But it loops through all the tickers, so there are delete buttons for all entries in the table on each row. If I don't use the for loop, I get the NoReverseMatch error. I know there is a way to solve this, but I have been working on it and searching for over two months.

I've also tried a while loop, and couldn't get it to work. I tried adding a delete form to the add_stock.html file with the corresponding request on the views.py file.

Links I've tried, but still couldn't solve:

ments-not-found-django

1 Answers1

1

You are using delete in 2 different places. In the first, you reference the wrong item:

{% for list_item in output %}
   ...
   {% url 'delete' item.id %} 

should be

{% url 'delete' list_item.id %}

In the second one, it is correct:

{% for item in ticker %}
   <a href="{% url 'delete' item.id %}"

Also, delete is a reserved word in many cases. I don't think that is the case here, but is still a bad habit. Change to delete_stock everywhere:

<a href="{% url 'delete_stock' list_item.id %}" ...>

def delete_stock(request, stock_id=None):

path('delete_stock/<stock_id>', views.delete_stock, name="delete_stock"),

Is stock_id an integer or string? To find out, print inside the loop in add_stock():

api = json.loads(api_request.content)
print(api)
output.append(api)

Also, the stock ID will come over as a string in the url, so if it is an integer, do:

item = Stock.objects.get(pk=int(stock_id))

or use:

path('delete_stock/<int:stock_id>', views.delete_stock, name="delete_stock"),

Do the other urls work?

BONUS HINT:

There is no need to have .html in your urls. That looks antiquated. Better form would be:

urlpatterns = [
    path('', views.home, name="home"),
    path('about', views.about, name="about"),
    path('add_stock', views.add_stock, name="add_stock"),
    path('delete_stock/<int:stock_id>', views.delete_stock, name="delete_stock"),
    path('news', views.news, name="news"),
    
]
GAEfan
  • 11,244
  • 2
  • 17
  • 33
  • Thank you, I tried updating it to {% url 'delete' list_item.id %} and delete the second one. But I still received the NoReverseMatch error. Is there a problem with the url as well, in the urls.py file? – Jenna C. Williams Aug 17 '20 at 05:17
  • To troubleshoot, add this to urls: `path('delete_stock', views.delete_stock, name="delete_stock"),`, `path('delete_stock/', views.delete_stock, name="delete_stock"),`. and then test for `stock_id` in the view. This will tell you if the problem is in your `{{output}}` in the template – GAEfan Aug 17 '20 at 16:23
  • Also, `print(api)` as in edit above to see what you're actually getting. You may be sending an empty list – GAEfan Aug 17 '20 at 16:33