Internal
Public Access
Fix task edit crashing after due_date/due_time save (regression from reminders)
The web edit/create/quick-add views and the sync endpoint assigned due_date/due_time/reminder_at straight from request data as raw strings. Django tolerates this at save() (types get coerced deep in the SQL layer), but the in-memory instance keeps the raw strings afterward. Task.reschedule_reminders(), added for per-task reminders and run from save() on that same instance, was the first code to actually operate on those fields before a page reload and crashed with a TypeError - which the service worker's 5xx-treated-as-offline fallback then masked as a misleading "you're offline" screen instead of a real error. Fixed by parsing with Django's parse_date/parse_time/parse_datetime at the point these values are read from the request/payload in tasks/views.py and sync/views.py, rather than trusting raw strings. 5 new regression tests exercise the actual views/endpoint with raw date/time strings and assert proper types land on the model. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
5359bf243a
commit
a27fcc4c69
+6
-5
@@ -7,6 +7,7 @@ from django.contrib.auth.decorators import login_required
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.utils import timezone
|
||||
from django.utils.dateparse import parse_date, parse_time
|
||||
from django.utils.http import url_has_allowed_host_and_scheme
|
||||
from django.views import View
|
||||
from django.views.decorators.http import require_POST
|
||||
@@ -466,10 +467,10 @@ class TaskDetailView(View):
|
||||
task.priority = priority
|
||||
|
||||
due_date = request.POST.get('due_date')
|
||||
task.due_date = due_date if due_date else None
|
||||
task.due_date = parse_date(due_date) if due_date else None
|
||||
|
||||
due_time = request.POST.get('due_time')
|
||||
task.due_time = due_time if due_time else None
|
||||
task.due_time = parse_time(due_time) if due_time else None
|
||||
|
||||
# Validate recurrence against allowed choices
|
||||
recurrence = request.POST.get('recurrence', 'none')
|
||||
@@ -540,8 +541,8 @@ class TaskCreateView(View):
|
||||
description=request.POST.get('description', ''),
|
||||
status=status,
|
||||
priority=priority,
|
||||
due_date=request.POST.get('due_date') or None,
|
||||
due_time=request.POST.get('due_time') or None,
|
||||
due_date=parse_date(request.POST.get('due_date')) if request.POST.get('due_date') else None,
|
||||
due_time=parse_time(request.POST.get('due_time')) if request.POST.get('due_time') else None,
|
||||
recurrence=recurrence,
|
||||
recurrence_rule=request.POST.get('recurrence_rule', '') if recurrence == 'custom' else '',
|
||||
)
|
||||
@@ -559,7 +560,7 @@ def task_quick_add(request):
|
||||
task = Task.objects.create(
|
||||
user=request.user,
|
||||
title=request.POST.get('title'),
|
||||
due_date=request.POST.get('due_date') or None,
|
||||
due_date=parse_date(request.POST.get('due_date')) if request.POST.get('due_date') else None,
|
||||
)
|
||||
# Handle optional tag
|
||||
tag_id = request.POST.get('tag')
|
||||
|
||||
Reference in New Issue
Block a user