Как исправить ошибку NoReverseMatch в таблице Django для кнопки удаления

Python версии 3.7.7 и Django версии 2.2.3. Код на Github https://github.com/jcwill415/Stock_Market_Web_App

Я хочу добавить кнопку удаления в последний столбец таблицы. Когда код находится за пределами таблицы, он удаляет запись из таблицы. Но когда код находится внутри таблицы, я получаю сообщение об ошибке NoReverseMatch:

  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"),
    
]

Что я пробовал Я пробовал использовать цикл for:

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

Но он проходит по всем тикерам, поэтому есть кнопки удаления для всех записей в таблице в каждой строке. Если я не использую цикл for, я получаю ошибку NoReverseMatch. Я знаю, что есть способ решить эту проблему, но я работал над этим и искал более двух месяцев.

Я также пробовал цикл while и не мог заставить его работать. Я попытался добавить форму удаления в файл add_stock.html с соответствующим запросом в файле views.py.

Ссылки, которые я пробовал, но все еще не нашел:

ments-not-found-django


person Jenna C. Williams    schedule 16.08.2020    source источник


Ответы (1)


Вы используете delete в двух разных местах. В первом случае вы ссылаетесь не на тот элемент:

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

должно быть

{% url 'delete' list_item.id %}

Во втором - правильно:

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

Кроме того, delete во многих случаях является зарезервированным словом. Я не думаю, что здесь так, но все же это плохая привычка. Меняем на delete_stock везде:

<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"),

stock_id целое число или строка? Чтобы узнать, напечатайте внутри цикла в add_stock():

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

Кроме того, идентификатор акции будет отображаться в виде строки в URL-адресе, поэтому, если это целое число, выполните:

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

или используйте:

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

Другие URL работают?

БОНУСНЫЙ СОВЕТ:

Нет необходимости указывать .html в ваших URL-адресах. Это выглядит устаревшим. Лучшая форма была бы:

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"),
    
]
person GAEfan    schedule 16.08.2020
comment
Спасибо, я попытался обновить его до {% url 'delete' list_item.id%} и удалить второй. Но я все равно получал ошибку NoReverseMatch. Есть ли проблема с URL-адресом в файле urls.py? - person Jenna C. Williams; 17.08.2020
comment
Для устранения неполадок добавьте это в URL-адреса: path('delete_stock', views.delete_stock, name="delete_stock"),, path('delete_stock/', views.delete_stock, name="delete_stock"),. а затем проверьте наличие stock_id в представлении. Это скажет вам, связана ли проблема с вашим {{output}} в шаблоне. - person GAEfan; 17.08.2020
comment
Кроме того, print(api), как в редактировании выше, чтобы увидеть, что вы на самом деле получаете. Возможно, вы отправляете пустой список - person GAEfan; 17.08.2020