Django 5.1.1
Python 3.12.4
HTMX 1.9.12
Goal:
The table loads and the 1st record or selected record appears in the index_2.html form and
can be edited/saved and also the user can add a new record if desired.
Problem: Also see Traceback file at the end.
App loads a table with pagination while tracking page# and 1st record displayed ‘id’ then includes
{% include ‘turnover_app/index_2.html’ %}
when index_2.html page tries to load get the hated NoReverseMatch Error (see below)
NOTE: If both HTMX buttons have a hard number in the hx-get=“{% url ‘turnover_app:edit_turn’ 12 %}”
the page loads fine without issue other than I obviously cannot use the htmx buttons
If either hx-get=“{% url ‘turnover_app:edit_turn’ tologs.pk %}” has a pk var or any var in it
then NoReverseMatch Error alerts.
urls.py (partial)
path('turnover_app/', views.turnover_index, name='turnover_index'),
path('edit_turn/<int:pk>/', views.edit_turn, name='edit_turn'),
path('turnover_index_2/<int:pk>/', views.turnover_index_2, name='turnover_index_2'),
views.py (partial)
def turnover_index(request, *args, **kwargs):
global _TOLOG_SRCH_ID_PAGE
tologs = ToLog.objects.all().order_by(_ORDBY)
parent_rcnt = tologs.count()
paginator = Paginator(tologs, _ITEMS_PER_PAGE)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
if type(page_number) == str:
conv_2_num = int(page_number)
if conv_2_num == 1:
rec_to_get = 0
else:
rec_to_get = (conv_2_num * _ITEMS_PER_PAGE)
rec_to_get = rec_to_get - _ITEMS_PER_PAGE
else: # page_number = <class 'NoneType'>
conv_2_num = 1
rec_to_get = (conv_2_num * _ITEMS_PER_PAGE)
rec_to_get = rec_to_get - _ITEMS_PER_PAGE
_TOLOG_SRCH_ID_PAGE=(tologs[rec_to_get].id)
TologPkRecID = _TOLOG_SRCH_ID_PAGE
template = 'turnover_app/index.html'
return render(request, template,{'TologPkRecID': TologPkRecID, 'page_obj': page_obj, 'count': tologs.count()})
def turnover_index_2(request, pk, *args, **kwargs):
if request.method == 'GET':
tologs = get_object_or_404(ToLog, pk=pk)
context = {}
context['tologs'] = tologs
context['form'] = ToLogForm(initial={
'id': tologs.id,
'social_title': tologs.social_title,
'ivanti_ticket' : tologs.ivanti_ticket,
'date_time': tologs.date_time,
'completed': tologs.completed,
'comments' : tologs.comments,
'noc_tech_name' : tologs.noc_tech_name,
'entrytype' : tologs.entrytype
})
template = 'turnover_app/index_2.html'
return render(request, template, context)
else: # POST request
pass
def edit_turn(request, pk):
if request.method == 'GET':
tolog = ToLog.objects.get(pk=pk)
context = {}
context['tolog'] = tolog
context['form'] = ToLogForm(initial={
'social_title': tolog.social_title,
'ivanti_ticket': tolog.ivanti_ticket,
'date_time': tolog.date_time,
'completed': tolog.completed,
'comments' : tolog.comments,
'noc_tech_name' : tolog.noc_tech_name,
'entrytype' : tolog.entrytype
})
template = 'turnover_app/index_2.html'
return render(request, template, context)
else:
tolog = ToLog.objects.get(pk=pk)
form = ToLogForm(request.POST, instance=tolog)
if not form.is_valid():
if form.is_valid():
form.save()
template = 'turnover_app/index_2.html'
return render(request, template, {'form': form,'tolog': tolog})
else:
template = 'turnover_app/index_2.html'
return render(request, template, {'form': form,'tolog': tolog})
index.html (partial)
<div class="container-fluid">
: : : :
<div id="turnList">
{% include 'turnover_app/turnover-list.html' %}
</div>
<div id="indx_2" class="col-6 col-md-4" hx-trigger="load" hx-get="{% url 'turnover_app:turnover_index_2' pk=TologPkRecID %}" hx-target="this">
{% include 'turnover_app/index_2.html' %}
</div>
turnover-list.html (partial)
{% if page_obj %}
<div class="table-responsive" style="height: 640px; overflow-y: auto;">
<table class="table table-striped w-300 ">
<form>
: : : : : : :
</form>
<tbody>
{% for tolog in page_obj %}
{% include 'turnover_app/turnover_row.html' %}
{% endfor %}
</tbody>
</table>
</div>
{% include 'turnover_app/pagination.html' %}
turnover_row.html (partial)
<tr>
<td class="text-primary" style="word-wrap: break-word;min-width: 80px;max-width: 280px; cursor: pointer;"
hx-get="{% url 'turnover_app:turnover_index_2' pk=tolog.pk %}"
hx-target="#indx_2"
hx-swap="#"
hx-trigger="click">
<u>{{ tolog.social_title }}</u>
</td>
: : : :
<td>
<button type="button"
class="btn-sm btn btn-outline-danger"
hx-get="{% url 'turnover_app:delete_turn' tolog.pk %}"
hx-target="#turnList"
hx-confirm="Are you sure you wish to delete?"
style="cursor: pointer;">
DEL
</button>
</td>
</tr>
index_2.html (partial)
<div class="container-fluid">
<form>
<div class="card mb-3" style="max-width:600px; min-width:600px;">
<div class="card-body">
<p class="card-text">Record Detail - TurnOver Log</p>
<div class="form-floating mb-1 w-75">
{% render_field form.social_title class="form-control" style="background-color: rgba(0,0,255,.1)" placeholder=form.text.label %}
<label for="id_social_title">Social Title:*</label>
{% for error in form.social_title.errors %}
<span class="text-danger">{{ error }}</span>
{% endfor %}
</div>
: : : : :
<div>
<button type="button"
class="btn-sm btn btn-outline-danger"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-post="{# url 'turnover_app:create_turn #}"
hx-target="#"
>
AddNew (no-op)
</button>
<button type="button"
class="btn-sm btn btn-outline-primary"
hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
hx-get="{% url 'turnover_app:edit_turn' 12 %}"
hx-target="#"
>
Edit (testing)
</button>
------Traceback -------
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/turnover_app/turnover_app/
Django Version: 5.1.1
Python Version: 3.12.4
Installed Applications:
['student',
'compressor',
'hyperapp',
'todo_app',
'turnover_app',
'mybook',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'home_app',
'crispy_forms',
'crispy_bootstrap5',
'console_app',
'django_bootstrap5',
'user.apps.UserConfig',
'django_tables2',
'debug_toolbar',
'django_htmx',
'htmx',
'singlepage',
'import_export',
'django_filters',
'widget_tweaks',
'rest_framework']
Installed Middleware:
['debug_toolbar.middleware.DebugToolbarMiddleware',
'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',
'django_htmx.middleware.HtmxMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware']
Template error:
In template C:\Users\EAI24909\OneDrive - Epson America\Desktop\Python Projects\epson\.epsonVE\enoc_proj\turnover_app\templates\turnover_app\index_2.html, error at line 86
Reverse for 'edit_turn' with arguments '('',)' not found. 1 pattern(s) tried: ['turnover_app/edit_turn/(?P<pk>[0-9]+)/\\Z']
76 : hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
77 : hx-post="{# url 'turnover_app:create_turn #}"
78 : hx-target="#"
79 : >
80 : AddNew (no-op)
81 : </button>
82 :
83 : <button type="button"
84 : class="btn-sm btn btn-outline-primary"
85 : hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'
86 : hx-get=" {% url 'turnover_app:edit_turn' tologs.pk %} "
87 : hx-target="#"
88 : >
89 : Edit (testing)
90 : </button>
91 :
92 :
93 : </div>
94 : <hr>
95 :
96 : <div class="table-responsive" style="height: 200px; overflow-y: auto;">
Traceback (most recent call last):
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\OneDrive - Epson America\Desktop\Python Projects\epson\.epsonVE\enoc_proj\turnover_app\views.py", line 130, in turnover_index
return render(request, template,{'TologPkRecID': TologPkRecID, 'page_obj': page_obj, 'count': tologs.count()})
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\shortcuts.py", line 25, in render
content = loader.render_to_string(template_name, context, request, using=using)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\loader.py", line 62, in render_to_string
return template.render(context, request)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\backends\django.py", line 107, in render
return self.template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 171, in render
return self._render(context)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\test\utils.py", line 114, in instrumented_test_render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\loader_tags.py", line 159, in render
return compiled_parent._render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\test\utils.py", line 114, in instrumented_test_render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\loader_tags.py", line 65, in render
result = block.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\loader_tags.py", line 210, in render
return template.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 173, in render
return self._render(context)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\test\utils.py", line 114, in instrumented_test_render
return self.nodelist.render(context)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 1008, in render
return SafeString("".join([node.render_annotated(context) for node in self]))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\base.py", line 969, in render_annotated
return self.render(context)
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\template\defaulttags.py", line 480, in render
url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\urls\base.py", line 88, in reverse
return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\EAI24909\.virtualenvs\.epsonVE-iknzfel_\Lib\site-packages\django\urls\resolvers.py", line 831, in _reverse_with_prefix
raise NoReverseMatch(msg)
^^^^^^^^^^^^^^^^^^^^^^^^^
Exception Type: NoReverseMatch at /turnover_app/turnover_app/
Exception Value: Reverse for 'edit_turn' with arguments '('',)' not found. 1 pattern(s) tried: ['turnover_app/edit_turn/(?P<pk>[0-9]+)/\\Z']