﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
35617	NoReverseMatch at /hyperapp/edit_notes/55/	John Barry		"Created a small app to make notes and initial test of AI LLM POC.

Entire app works as intended except when editing notes. Always throws a dreaded ""NoReverseMatch""  (added word doc of the entire error).
NOTE: I deleted the all the *.html files and views.py functions, urls.py etc.  and started all over again copy and pasting the code from another app I have written and used many times.  Basically only having to change the namespace, models info etc. Only this app (hyperapp) is having the issue.

The error is in edit_notes.html  hx-post=""{% url 'hyperapp:notes_submit' item.pk %}"" 

I will add the relevant code below for viewing.

**urls.py**
'''
from django.urls import path, include
from django.contrib import admin
from django.contrib.auth import login, logout
from django.urls import reverse

from . import views

app_name = 'hyperapp'   

urlpatterns = [
  path(""hyperapp/"", views.hyperindex, name=""hyperhome""),
  path(""add"", views.add_notes_view, name=""add_notes_view""),
]
htmxpatterns = [
  path(""delete/<int:pk>/"", views.delete_notes_view, name=""delete_notes""),
  path('edit_notes/<int:pk>/', views.edit_notes, name='edit_notes'),
  path('notes_submit/<int:pk>/', views.notes_submit, name='notes_submit'),   
  path('setOrderby/', views.setOrderby, name='setOrderby'), 
  path('search_results_view/', views.search_results_view, name='search_results_view'),     
]
urlpatterns += htmxpatterns

'''

**models.py**
'''
from django.db import models

class NotesModel(models.Model):
  content = models.CharField(max_length=1000,blank=True,null=True)
  created_date = models.DateTimeField(auto_now_add=True)
  
  def __str__(self):
        return self.content
'''

**views.py**
'''

from .models import NotesModel

_ORDBY = ('-id')                                             # setting default global var for order_by
_ITEMS_PER_PAGE = 4   

def hyperindex(request):
  notes = NotesModel.objects.all().order_by(_ORDBY) # new
  paginator = Paginator(notes, _ITEMS_PER_PAGE)    
  page_number = request.GET.get('page')          
  page_obj = paginator.get_page(page_number) 
  template = 'hyperapp/hyperindex.html'     
  return render(request, template, {'page_obj': page_obj, 'count': notes.count()})
    
@require_http_methods([""GET"", ""POST""])
def setOrderby(request):
    template = 'hyperapp/lists.html'  
    global _ORDBY                                               # get global var ready for change
    if request.method == ""POST"":
        if request.POST.get(""wordup"", None) is None:
            _ORDBY = ('-id')                                    # something happened with request so reset to (-id) 
        else:
            inputtxt = request.POST.get('wordup')
            if inputtxt == ""order_by_content"":
                if _ORDBY == ('content'):                         # check to see if _ORDBY already equals 'title'
                    _ORDBY = ('-id')                            # change order by now
                else:
                    _ORDBY = ('content')
            else:                                               # default _ORDBY = ('-id') if inputtxt had an issue
                _ORDBY = ('-id')
            notes = NotesModel.objects.all().order_by(_ORDBY)         # NOTE: _ORDBY is a variable 
            paginator = Paginator(notes, _ITEMS_PER_PAGE)    
            page_number = request.GET.get('page')           
            page_obj = paginator.get_page(page_number)      
    return render(request, template, {'page_obj': page_obj, 'count': notes.count()})

@require_http_methods([""GET"", ""POST""])
def add_notes_view(request):
  content = request.POST.get('note_content')                                               # new
  note = NotesModel.objects.create(content=content)                                   # new
  note.save()                                                                         # new  
  notes = NotesModel.objects.all().order_by(_ORDBY)                                   # new
  paginator = Paginator(notes, _ITEMS_PER_PAGE)                                       # new 
  page_number = request.GET.get('page')                                               # new
  page_obj = paginator.get_page(page_number)                                          # new
  template = 'hyperapp/lists.html'                                                    # new
  return render(request, template, {'page_obj': page_obj, 'count': notes.count()})    # new


def delete_notes_view(request,pk):
  note = NotesModel.objects.get(pk=pk)    # changed from id=pk to pk=pk
  note.delete()
  notes = NotesModel.objects.all().order_by(_ORDBY)
  paginator = Paginator(notes, _ITEMS_PER_PAGE)       
  page_number = request.GET.get('page')              
  page_obj = paginator.get_page(page_number)        
  template = 'hyperapp/lists.html'
  return render(request, template, {'page_obj': page_obj, 'count': notes.count()}) 


class NoteForm(forms.ModelForm):
    class Meta:
        model = NotesModel
        exclude = []
         
        
@require_http_methods([""GET"", ""POST""])
def edit_notes(request, pk):
    note = NotesModel.objects.get(pk=pk)
    context = {}
    context['note'] = note
    print(pk)
    context['form'] = NoteForm(initial={
        'content': note.content,
        'created_date' : note.created_date                
    })
    print(""JOHN"", context)
    template = 'hyperapp/edit_notes.html'
    return render(request, template, context)


@require_http_methods([""GET"", ""POST""])
def notes_submit(request, pk):    # changed edit_notes_submit  to notes_submit
    print(""notes_submit"")
    context = {}
    note = NotesModel.objects.get(pk=pk)
    context['note'] = note
    print(""context jbh:"", context)
    
    if request.method == 'POST':
          print(""post"")
          form = NoteForm(request.POST, instance=note)
          if form.is_valid():
            form.save()
            notes = NotesModel.objects.all().order_by(_ORDBY)
          else:
            template = 'hyperapp/edit_note.html'
            return render(request, template, context)
    template = 'hyperapp/note_row.html'
    return render(request, template, context)
  
  
@require_http_methods([""GET"", ""POST""])
def search_results_view(request):
    query = request.GET.get('search', '')   		        # NOTE: ‘search’  is from the input control in search html file
    note = NotesModel.objects.all()
    
    if query:
        #notes = note.filter(content__icontains=query)        # NOTE: 'title' is field from models.py
        notes = note.filter(content__startswith=query)
        paginator = Paginator(notes, _ITEMS_PER_PAGE)    
        page_number = request.GET.get('page')           
        page_obj = paginator.get_page(page_number)      
    else:                                                   # if we get here then there was no query match 
        notes = []
        notes = NotesModel.objects.all().order_by(_ORDBY)
        paginator = Paginator(notes, _ITEMS_PER_PAGE)    
        page_number = request.GET.get('page')           
        page_obj = paginator.get_page(page_number)      
        template = 'hyperapp/lists.html'
        return render(request, template, {'page_obj': page_obj, 'count': notes.count()}) 
    context = {'page_obj': page_obj}                         
    template = 'hyperapp/lists.html'
    return render(request, template, context)
'''

**base.html**

'''
{% load static %}
<!doctype html>
<html lang=""en"">
  <head>
    <meta charset=""utf-8"">
    <meta name=""viewport"" content=""width=device-width, initial-scale=1"">
    <title>{% block title %}{% endblock %}</title>
    <!-- Bootstrap 5 css -->
    <link rel=""stylesheet"" href=""{% static 'css/bootstrap.min.css' %}"">
  </head>
  <body>
        <div class=""container mt-5"">
            {% block content %}
            
            {% endblock %}
        </div>
      <script src=""{% static 'js/bootstrap.bundle.min.js' %}""></script>

      <script src=""{% static 'js/htmx.min.js' %}""></script>

      {% block js_script %}
      {% endblock %}

      <script>
        document.body.addEventListener('htmx:configRequest', (event) => {
          event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
        })
      </script>
  </body>
</html>
'''
**hyperindex.html**

'''
{% extends 'hyperapp/base.html' %}
{# load static #}                   

{% block title %} Home {% endblock %}
{% block content %}

<h3 class=""my-5"">Notes</h3>
{% csrf_token %}
<!--  this section is for the search box -->
<input class=""form-control"" type=""search""
       name=""search"" placeholder=""Begin Typing To Search for a title..."" 
       hx-get=""{% url 'hyperapp:search_results_view' %}"" 
       hx-trigger=""keyup changed delay:500ms""
       hx-target=""#notes_results"">   
<br>

<form hx-post=""{% url 'hyperapp:add_notes_view' %}"" hx-target=""#notes_results"" class=""mx-auto"" hx-on::after-request=""this.reset()"">
  {% csrf_token %}
  <div class=""mb-3 row align-items-center"">
      <label for=""noteText"" class=""col-auto col-form-label"">Enter new notes here: </label> 
      <div class=""col-6"">
        <input type=""text"" name=""note_content"" class=""form-control"" placeholder=""Enter notes here"">
      </div>

      <div class=""col-auto"">
          <button class=""btn-sm btn-outline-primary"">Add Notes</button>
      </div>
  </div>
</form>

<div id=""notes_results"">
    {% include 'hyperapp/lists.html' %}
</div>

 <!-- chat col -->
 <div class=""col"">
  <div class=""card"">
    <div class=""card-header"">
      eAI Chat
    </div>
    <div class=""card-body"">
      <div class=""overflow-auto p-3 bg-light"" style=""width: 450px; height: 600px;"">
      <p id=""results""></p>
      </div>
    </div>
      
    <div class=""card-footer text-body-secondary"">
      <form action="""">

      <input type=""text"" name=""search_query"" class=""form-control"" placeholder=""Ask A question""
      hx-post=""{% url 'hyperapp:ask_llm' %}""
      hx-target=""#results""
      hx-trigger=""keyup changed delay:5s""
      hx-swap=""beforeend""
      >
      <br>
      <button type=""reset"" class=""btn btn-danger"">Clear</button> 
      <button type=""Submit"" class=""btn btn-primary""
      hx-post=""{% url 'hyperapp:ask_llm' %}""
      hx-target=""#results""
      hx-swap=""beforeend""

      >Send</button> 
      </form>
    
    </div>
    
  </div> 
</div>
</div>
</div>

{% endblock %}

{% block js_script %}
<script>
  document.body.addEventListener('htmx:configRequest', (event) => {
      event.detail.headers['X-CSRFToken'] = '{{ csrf_token }}';
  })
</script>
{% endblock %}

'''
**lists.html**

'''

{% if page_obj %}   
<!-- NOTE: this option on the next ** line overflow-y: auto; ** is what allows scrollable tables but when I 
 inserted the code for pagination this feature seems to disable itself. interesting-->
<div class=""table-responsive"" style=""height: 500px; overflow-y: auto;"">
  <table  class=""table table-striped w-100 d-block d-md-table"">
    <form>
    <thead>
        <div>
          <input type=""hidden"" id=""txword"" name=""wordup"" value=""order_by_content"">  
        <th>
          <a class="""" href="""" 
            hx-headers='{""X-CSRFToken"": ""{{ csrf_token }}""}'
            hx-post=""{% url 'hyperapp:setOrderby' %}""
            hx-trigger=""click""
            hx-target=""#notes_results""
            hx-include=""[name='wordup']""
            >Content</a>
        </th>
        </div>
        
        <th>Created</th>
    </thead>
    </form>
    <tbody>
      {# for item in notes #}
      {% for item in page_obj %}
            {% include 'hyperapp/note_row.html' %}
      {% endfor %}
    </tbody>
  </table>
</div>


    <div class=""btn-group"" role=""group"" aria-label=""Item pagination"">
        {% if page_obj.has_previous %}
            <a href=""?page={{ page_obj.previous_page_number }}"" class=""btn btn-outline-primary"">&laquo;</a>
        {% endif %}
        {% for page_number in page_obj.paginator.page_range %}
            {% if page_obj.number == page_number %}
                <button class=""btn btn-outline-primary active"">
                    <span>{{ page_number }} <span class=""sr-only"">(current)</span></span>
                </button>
            {% else %}
                <a href=""?page={{ page_number }}"" class=""btn btn-outline-primary"">
                    {{ page_number }}
                </a>
            {% endif %}
        {% endfor %}
        {% if page_obj.has_next %}
            <a href=""?page={{ page_obj.next_page_number }}"" class=""btn btn-outline-primary"">&raquo;</a>
        {% endif %}
    </div>
    <div>Total record count: {{ count }}</div>

{% else %}
<h5>Currently, you don't have any notes. Or there were no search matches.</h5>
{% endif %}

'''

**note_row.html**

'''
<tr>
  <td style=""word-wrap: break-word;min-width: 60px;max-width: 60px;"">{{ item.content }}</td>
  <td style=""word-wrap: break-word;min-width: 50px;max-width: 50px;"">{{ item.created_date }}</td>
 
  <td>
    <button type=""button"" 
    class=""btn-sm btn-outline-danger""  
    hx-get=""{% url 'hyperapp:delete_notes' item.pk %}""
    hx-target=""#notes_results""
    hx-confirm=""Are you sure you wish to delete?""  
    style=""cursor: pointer;"">
    DEL
    </button>
 
    <button type=""button""
    class=""btn-sm btn-outline-warning"" 
    hx-get=""{% url 'hyperapp:edit_notes' item.pk %}"" 
    hx-target=""closest tr"" 
    hx-swap=""outerHTML""
    style=""cursor: pointer;"">
    Edit
    </button>
  </td>

</tr>
'''

edit_notes.html

'''
<tr>
  <td style=""word-wrap: break-word;min-width: 60px;max-width: 60px;"">{{ form.content }}
      {{ form.content.errors }} 
  </td>
  <td>{{ form.created_date }}
      {{ form.created_date.errors }} 
  </td>
  
<td>
  <button type=""button"" 
  class=""btn-sm btn-outline-success"" 
  hx-post=""{% url 'hyperapp:notes_submit' item.pk %}"" 
  hx-target=""closest tr"" 
  hx-swap=""outerHTML"" 
  hx-include=""closest tr"" >
  Save
  </button>

  <button type=""button"" 
  class=""btn-sm btn-outline-dark"" 
  hx-get=""{% url 'hyperapp:notes_submit' item.pk %}"" 
  hx-target=""closest tr"" 
  hx-swap=""outerHTML"">
  Cancel
  </button>
</td> 
</tr>
'''"	Uncategorized	closed	Uncategorized	5.0	Normal	invalid	NoReverseMatch	John Barry	Unreviewed	0	0	0	0	0	0
