I am currently try make a task manager such that there are folders which have tasks in them, I have been stuck on this problem for hours now and am not sure at all what is the issue
this is 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"),
]
this is 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
this is 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})
I initially tried it with multiple slugs like this
path('<slug:folder_slug>/<slug:task_slug>/', views.task_page,name="task-page"),
then I opted to use task_id instead thinking it was the issue with multiple slugs but nope folder-page i.e.
def tasks_list(request, slug): #in views.py
itself is not rendering and I am getting this error
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']
at this line
<a href="{% url 'tasks:task-page' folder_slug=folder.slug task_id=task.id %}">
in 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 %}
Not sure what to do.
I have tried using this too
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})
2
Answers
I got it working after getting the idea that I could use the task title as a slug instead of the user writing one so
this is models.py
CreateTask form to exclude slug from fields
views.py
urls.py
tasks_list.html
In your case, the error message points out that the task_id is empty. This means that at some point in your loop, a task object does not have an id attribute, or the tasks list is empty. please adjust your code with adding
if else
in your loop to check iftask.id
exists: here is an example,: