Как решить эту ошибку NoReverseMatch?

В настоящее время я пытаюсь сделать диспетчер задач таким образом, чтобы в нем были папки с заданиями, я застрял на этой проблеме уже несколько часов назад и совершенно не уверен в том, в чем проблема

это urls.py

from django.urls import path
from . import views

app_name= 'tasks'

urlpatterns = [
    path('', views.folders_list,name="list"),
    path('new-folder/', views.folder_new,name="new-folder"),
    path('<slug:slug>', views.tasks_list,name="folder-page"),
    path('<slug:folder_slug>/<int:task_id>/', views.task_page,name="task-page"),
    path('new-task/', views.task_new,name="new-task"),  
]

это models.py

from django.db import models
from django.contrib.auth.models import User
# from .models import Folder

# Create your models here.
class Folder(models.Model):
  folder_id=models.AutoField(primary_key=True)
  title=models.CharField(max_length=75)
  created=models.DateTimeField(auto_now_add=True)
  slug=models.SlugField()
  author = models.ForeignKey(User, on_delete=models.CASCADE, default=None)

class Task(models.Model):
  PRIORITY_CHOICES=[
    ('LOW','LOW'),
    ('MEDIUM','MEDIUM'),
    ('HIGH','HIGH'),
  ]
  task_id=models.AutoField(primary_key=True)
  title=models.CharField(max_length=75)
  description=models.TextField()
  slug=models.SlugField()
  deadline=models.DateField()
  uploaded=models.DateTimeField(auto_now_add=True)
  author = models.ForeignKey(User, on_delete=models.CASCADE, default=None)
  folder = models.ForeignKey('Folder', on_delete=models.CASCADE, default=None)
  priority = models.CharField(max_length=10, choices=PRIORITY_CHOICES, default='LOW')

  def __str__(self):
    return self.title

это views.py

from django.shortcuts import render,redirect
from django.utils.regex_helper import re
from .models import Task,Folder
from django.contrib.auth.decorators import login_required
from django.shortcuts import get_object_or_404
from . import forms

# Create your views here.

@login_required(login_url="/users/login/")
def folders_list(request):
    user_folders = Folder.objects.filter(author=request.user)
    return render(request, 'tasks/folders_list.html', {'folders': user_folders})

#as folder_page == tasks_list.html
def tasks_list(request, slug):
  # folder=get_object_or_404(Folder,slug=slug)
  folder=Folder.objects.get(slug=slug)
  folder_tasks = Task.objects.filter(folder=folder)
  return render(request, 'tasks/tasks_list.html', {'folder':folder,'tasks': folder_tasks})
    

def task_page(request, folder_slug, task_id):
    folder = get_object_or_404(Folder, slug=folder_slug)
    task = get_object_or_404(Task, pk=task_id, folder=folder)
    return render(request, 'tasks/task_page.html', {'task': task})


def folder_new(request):
  if request.method=='POST':
    form=forms.CreateFolder(request.POST)
    if form.is_valid():
      newfolder=form.save(commit=False)
      newfolder.author=request.user
      newfolder.save()
      return redirect('tasks:list')
  else:
    form=forms.CreateFolder()
  return render(request, 'tasks/folder_new.html', {'form':form})

def task_new(request):
  if request.method=='POST':
    form=forms.CreateTask(request.POST)
    if form.is_valid():
      newtask=form.save(commit=False)
      newtask.author=request.user
      newtask.save()
      return redirect('tasks:list')
  else:
    form=forms.CreateTask()
  return render(request, 'tasks/task_new.html', {'form':form})

Сначала я попробовал с несколькими пулями вот так

path('<slug:folder_slug>/<slug:task_slug>/', views.task_page,name="task-page"),

тогда я решил использовать task_id вместо этого, думая, что это проблема с множественными слизнями, но нет, папка-страница, т.е.

def tasks_list(request, slug): #in views.py

сам не отрисовывается, и я получаю эту ошибку

NoReverseMatch at /tasks/new-folder
Reverse for 'task-page' with keyword arguments '{'folder_slug': 'new-folder', 'task_id': ''}' not found. 1 pattern(s) tried: ['tasks/(?P<folder_slug>[-a-zA-Z0-9_]+)/(?P<task_id>[0-9]+)/\\Z']

в этой строке

<a href="{% url 'tasks:task-page' folder_slug=folder.slug task_id=task.id %}">

в файле tasks_list.html

{% extends 'layout.html' %}

{% block title %}
    Tasks
{% endblock %}

{% block content %}
  <section>
    <h1> {{folder.title}}</h1>
    <h1>Tasks</h1>

    {% for task in tasks %}
      <article class="task">
          <h2>
            <a href="{% url 'tasks:task-page' folder_slug=folder.slug task_id=task.id %}">
              {{ task.title }}
            </a>
          </h2>
          <p>{{ task.uploaded }} by {{ task.author}}</p>
          <p>{{ task.deadline}}</p>
      </article>
    {% endfor %}
    <form action="{% url 'tasks:new-task' %}" method="post">
      {% csrf_token %}
      <button class="form-submit">New Task</button>
    </form>
 </section>
{% endblock %}

Не знаю, что делать.

Я тоже пробовал использовать это

def tasks_list(request, slug):
    folder = get_object_or_404(Folder, slug=slug)
    folder_tasks = Task.objects.filter(folder=folder)
    return render(request, 'tasks/tasks_list.html', {'folder': folder, 'tasks': folder_tasks})

В вашем случае сообщение об ошибке указывает на то, что task_id пуст. Это означает, что в какой-то момент в вашем цикле у объекта задачи нет атрибута id, или список задач пуст. пожалуйста, скорректируйте ваш код, добавив if else в ваш цикл, чтобы проверить, существует ли task.id: вот пример,:

{% for task in tasks %}
      {% if task.id %}
        <article class="task">
          <h2>
            <a href="{% url 'tasks:task-page' folder_slug=folder.slug task_id=task.id %}">
              {{ task.title }}
            </a>
          </h2>
          <p>{{ task.uploaded }} by {{ task.author }}</p>
          <p>{{ task.deadline }}</p>
        </article>
      {% else %}
        <article class="task">
          <h2>{{ task.title }}</h2>
          <p>{{ task.uploaded }} by {{ task.author }}</p>
          <p>{{ task.deadline }}</p>
          <p><strong>Error: Missing task ID</strong></p>
        </article>
      {% endif %}
    {% endfor %}

У меня получилось, когда я понял, что можно использовать название задачи в качестве slug, а не писать его самому пользователю, так что

это models.py

from django.utils.text import slugify

class Task(models.Model):


  task_id=models.AutoField(primary_key=True)
  title=models.CharField(max_length=75)
  .
  .
  .# rest of the attributes
  
  def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.title)
        super(Task, self).save(*args, **kwargs)

Форма создания задачи для исключения slug из полей

views.py

def task_page(request, folder_slug, task_slug):
    folder = get_object_or_404(Folder, slug=folder_slug)
    task = get_object_or_404(Task, slug=task_slug, folder=folder)
    return render(request, 'tasks/task_page.html', {'task': task})

urls.py

path('<slug:folder_slug>/<slug:task_slug>/', views.task_page,name="task-page")

tasks_list.html

<a href="{% url 'tasks:task-page' folder_slug=folder.slug task_slug=task.slug %}">
Вернуться на верх