Rename Item model to Task
- With matching model, view, template changes
This commit is contained in:
parent
a2d02b0a8c
commit
d3d8d5e46c
15 changed files with 133 additions and 119 deletions
1
setup.py
1
setup.py
|
@ -21,7 +21,6 @@ setup(
|
|||
'License :: OSI Approved :: BSD License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Programming Language :: Python :: 2',
|
||||
'Programming Language :: Python :: 3',
|
||||
'Topic :: Office/Business :: Groupware',
|
||||
'Topic :: Software Development :: Bug Tracking',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
from django.contrib import admin
|
||||
from todo.models import Item, TaskList, Comment
|
||||
from todo.models import Task, TaskList, Comment
|
||||
|
||||
|
||||
class ItemAdmin(admin.ModelAdmin):
|
||||
class TaskAdmin(admin.ModelAdmin):
|
||||
list_display = ('title', 'task_list', 'completed', 'priority', 'due_date')
|
||||
list_filter = ('task_list',)
|
||||
ordering = ('priority',)
|
||||
|
@ -15,4 +15,4 @@ class CommentAdmin(admin.ModelAdmin):
|
|||
|
||||
admin.site.register(TaskList)
|
||||
admin.site.register(Comment, CommentAdmin)
|
||||
admin.site.register(Item, ItemAdmin)
|
||||
admin.site.register(Task, TaskAdmin)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django import forms
|
||||
from django.forms import ModelForm
|
||||
from django.contrib.auth.models import Group
|
||||
from todo.models import Item, TaskList
|
||||
from todo.models import Task, TaskList
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@ class AddTaskListForm(ModelForm):
|
|||
exclude = []
|
||||
|
||||
|
||||
class AddEditItemForm(ModelForm):
|
||||
class AddEditTaskForm(ModelForm):
|
||||
"""The picklist showing the users to which a new task can be assigned
|
||||
must find other members of the groups the current list belongs to."""
|
||||
|
||||
|
@ -43,11 +43,11 @@ class AddEditItemForm(ModelForm):
|
|||
widget=forms.Textarea(), required=False)
|
||||
|
||||
class Meta:
|
||||
model = Item
|
||||
model = Task
|
||||
exclude = []
|
||||
|
||||
|
||||
class AddExternalItemForm(ModelForm):
|
||||
class AddExternalTaskForm(ModelForm):
|
||||
"""Form to allow users who are not part of the GTD system to file a ticket."""
|
||||
|
||||
title = forms.CharField(
|
||||
|
@ -63,7 +63,7 @@ class AddExternalItemForm(ModelForm):
|
|||
)
|
||||
|
||||
class Meta:
|
||||
model = Item
|
||||
model = Task
|
||||
exclude = (
|
||||
'task_list', 'created_date', 'due_date', 'created_by', 'assigned_to', 'completed', 'completed_date', )
|
||||
|
||||
|
|
19
todo/migrations/0006_rename_item_model.py
Normal file
19
todo/migrations/0006_rename_item_model.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Generated by Django 2.0.3 on 2018-03-28 22:40
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('todo', '0005_auto_20180212_2325'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='Item',
|
||||
new_name='Task',
|
||||
),
|
||||
]
|
|
@ -1,14 +1,12 @@
|
|||
from __future__ import unicode_literals
|
||||
import datetime
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import Group
|
||||
from django.urls import reverse
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import Group
|
||||
from django.db import models
|
||||
from django.urls import reverse
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class TaskList(models.Model):
|
||||
name = models.CharField(max_length=60)
|
||||
slug = models.SlugField(default='',)
|
||||
|
@ -25,8 +23,7 @@ class TaskList(models.Model):
|
|||
unique_together = ("group", "slug")
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Item(models.Model):
|
||||
class Task(models.Model):
|
||||
title = models.CharField(max_length=140)
|
||||
task_list = models.ForeignKey(TaskList, on_delete=models.CASCADE, null=True)
|
||||
created_date = models.DateField(auto_now=True)
|
||||
|
@ -41,7 +38,7 @@ class Item(models.Model):
|
|||
|
||||
# Has due date for an instance of this object passed?
|
||||
def overdue_status(self):
|
||||
"Returns whether the item's due date has passed or not."
|
||||
"Returns whether the Tasks's due date has passed or not."
|
||||
if self.due_date and datetime.date.today() > self.due_date:
|
||||
return True
|
||||
|
||||
|
@ -51,25 +48,24 @@ class Item(models.Model):
|
|||
def get_absolute_url(self):
|
||||
return reverse('todo:task_detail', kwargs={'task_id': self.id, })
|
||||
|
||||
# Auto-set the item creation / completed date
|
||||
# Auto-set the Task creation / completed date
|
||||
def save(self, **kwargs):
|
||||
# If Item is being marked complete, set the completed_date
|
||||
# If Task is being marked complete, set the completed_date
|
||||
if self.completed:
|
||||
self.completed_date = datetime.datetime.now()
|
||||
super(Item, self).save()
|
||||
super(Task, self).save()
|
||||
|
||||
class Meta:
|
||||
ordering = ["priority"]
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Comment(models.Model):
|
||||
"""
|
||||
Not using Django's built-in comments because we want to be able to save
|
||||
a comment and change task details at the same time. Rolling our own since it's easy.
|
||||
"""
|
||||
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
|
||||
task = models.ForeignKey(Item, on_delete=models.CASCADE)
|
||||
task = models.ForeignKey(Task, on_delete=models.CASCADE)
|
||||
date = models.DateTimeField(default=datetime.datetime.now)
|
||||
body = models.TextField(blank=True)
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
<p>Category tally:</p>
|
||||
|
||||
<ul>
|
||||
<li>Incomplete: {{ item_count_undone }} </li>
|
||||
<li>Complete: {{ item_count_done }} </li>
|
||||
<li>Incomplete: {{ task_count_undone }} </li>
|
||||
<li>Complete: {{ task_count_done }} </li>
|
||||
<li>
|
||||
<strong>Total: {{ item_count_total }}</strong>
|
||||
<strong>Total: {{ task_count_total }}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<label for="id_assigned_to">Assigned To</label>
|
||||
{# See todo.forms.AddEditItemForm #}
|
||||
{# See todo.forms.AddEditTaskForm #}
|
||||
{{form.assigned_to}}
|
||||
</div>
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<hr />
|
||||
{% endif %}
|
||||
|
||||
{% if items %}
|
||||
{% if tasks %}
|
||||
{% if list_slug == "mine" %}
|
||||
<h1>Tasks assigned to me (in all groups)</h1>
|
||||
{% else %}
|
||||
|
@ -37,7 +37,7 @@
|
|||
<th>Del</th>
|
||||
</tr>
|
||||
|
||||
{% for task in items %}
|
||||
{% for task in tasks %}
|
||||
<tr id="{{ task.id }}">
|
||||
<td>
|
||||
<input type="checkbox" name="toggle_done_tasks"
|
||||
|
@ -80,7 +80,7 @@
|
|||
|
||||
</form>
|
||||
{% else %}
|
||||
<h4>No items on this list yet (add one!)</h4>
|
||||
<h4>No tasks on this list yet (add one!)</h4>
|
||||
{% include 'todo/include/toggle_delete.html' %}
|
||||
|
||||
{% endif %}
|
||||
|
|
|
@ -5,16 +5,16 @@
|
|||
{% block content %}
|
||||
<h1>Todo Lists</h1>
|
||||
|
||||
<p>{{ item_count }} items in {{ list_count }} list{{ list_count|pluralize }}</p>
|
||||
<p>{{ task_count }} tasks in {{ list_count }} list{{ list_count|pluralize }}</p>
|
||||
|
||||
{% regroup lists by group as section_list %}
|
||||
{% for group in section_list %}
|
||||
<h3>Group: {{ group.grouper }}</h3>
|
||||
<ul class="list-group mb-4">
|
||||
{% for item in group.list %}
|
||||
{% for task in group.list %}
|
||||
<li class="list-group-item d-flex justify-content-between align-items-center">
|
||||
<a href="{% url 'todo:list_detail' item.id item.slug %}">{{ item.name }}</a>
|
||||
<span class="badge badge-primary badge-pill">{{ item.item_set.count }}</span>
|
||||
<a href="{% url 'todo:list_detail' task.id task.slug %}">{{ task.name }}</a>
|
||||
<span class="badge badge-primary badge-pill">{{ task.task_set.count }}</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
{% block content_title %}<h2 class="page_title">Search</h2>{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if found_items %}
|
||||
<h2>{{found_items.count}} search results for term: "{{ query_string }}"</h2>
|
||||
{% if found_tasks %}
|
||||
<h2>{{found_tasks.count}} search results for term: "{{ query_string }}"</h2>
|
||||
<div class="post_list">
|
||||
{% for f in found_items %}
|
||||
{% for f in found_tasks %}
|
||||
<p>
|
||||
<strong>
|
||||
<a href="{% url 'todo:task_detail' f.id %}">{{ f.title }}</a>
|
||||
|
|
|
@ -2,7 +2,7 @@ import pytest
|
|||
|
||||
from django.contrib.auth.models import Group
|
||||
|
||||
from todo.models import Item, TaskList
|
||||
from todo.models import Task, TaskList
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
@ -13,14 +13,14 @@ def todo_setup(django_user_model):
|
|||
u1 = django_user_model.objects.create_user(username="u1", password="password", email="u1@example.com")
|
||||
u1.groups.add(g1)
|
||||
tlist1 = TaskList.objects.create(group=g1, name="Zip", slug="zip")
|
||||
Item.objects.create(created_by=u1, title="Task 1", task_list=tlist1, priority=1)
|
||||
Item.objects.create(created_by=u1, title="Task 2", task_list=tlist1, priority=2, completed=True)
|
||||
Item.objects.create(created_by=u1, title="Task 3", task_list=tlist1, priority=3)
|
||||
Task.objects.create(created_by=u1, title="Task 1", task_list=tlist1, priority=1)
|
||||
Task.objects.create(created_by=u1, title="Task 2", task_list=tlist1, priority=2, completed=True)
|
||||
Task.objects.create(created_by=u1, title="Task 3", task_list=tlist1, priority=3)
|
||||
|
||||
g2 = Group.objects.create(name="Workgroup Two")
|
||||
u2 = django_user_model.objects.create_user(username="u2", password="password", email="u2@example.com")
|
||||
u2.groups.add(g2)
|
||||
tlist2 = TaskList.objects.create(group=g2, name="Zap", slug="zap")
|
||||
Item.objects.create(created_by=u2, title="Task 1", task_list=tlist2, priority=1)
|
||||
Item.objects.create(created_by=u2, title="Task 2", task_list=tlist2, priority=2, completed=True)
|
||||
Item.objects.create(created_by=u2, title="Task 3", task_list=tlist2, priority=3)
|
||||
Task.objects.create(created_by=u2, title="Task 1", task_list=tlist2, priority=1)
|
||||
Task.objects.create(created_by=u2, title="Task 2", task_list=tlist2, priority=2, completed=True)
|
||||
Task.objects.create(created_by=u2, title="Task 3", task_list=tlist2, priority=3)
|
||||
|
|
|
@ -2,7 +2,7 @@ import pytest
|
|||
|
||||
from django.core import mail
|
||||
|
||||
from todo.models import Item, Comment
|
||||
from todo.models import Task, Comment
|
||||
from todo.utils import toggle_done, toggle_deleted, send_notify_mail, send_email_to_thread_participants
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ def email_backend_setup(settings):
|
|||
def test_toggle_done(todo_setup):
|
||||
"""Utility function takes an array of POSTed IDs and changes their `completed` status.
|
||||
"""
|
||||
u1_tasks = Item.objects.filter(created_by__username="u1")
|
||||
u1_tasks = Task.objects.filter(created_by__username="u1")
|
||||
completed = u1_tasks.filter(completed=True)
|
||||
incomplete = u1_tasks.filter(completed=False)
|
||||
|
||||
|
@ -38,13 +38,13 @@ def test_toggle_done(todo_setup):
|
|||
def test_toggle_deleted(todo_setup):
|
||||
"""Unlike toggle_done, delete means delete, so it's not really a toggle.
|
||||
"""
|
||||
u1_tasks = Item.objects.filter(created_by__username="u1")
|
||||
u1_tasks = Task.objects.filter(created_by__username="u1")
|
||||
assert u1_tasks.count() == 3
|
||||
t1 = u1_tasks.first()
|
||||
t2 = u1_tasks.last()
|
||||
|
||||
toggle_deleted([t1.id, t2.id, ])
|
||||
u1_tasks = Item.objects.filter(created_by__username="u1")
|
||||
u1_tasks = Task.objects.filter(created_by__username="u1")
|
||||
assert u1_tasks.count() == 1
|
||||
|
||||
|
||||
|
@ -56,7 +56,7 @@ def test_send_notify_mail_not_me(todo_setup, django_user_model, email_backend_se
|
|||
u1 = django_user_model.objects.get(username="u1")
|
||||
u2 = django_user_model.objects.get(username="u2")
|
||||
|
||||
task = Item.objects.filter(created_by=u1).first()
|
||||
task = Task.objects.filter(created_by=u1).first()
|
||||
task.assigned_to = u2
|
||||
task.save()
|
||||
send_notify_mail(task)
|
||||
|
@ -68,7 +68,7 @@ def test_send_notify_mail_myself(todo_setup, django_user_model, email_backend_se
|
|||
"""
|
||||
|
||||
u1 = django_user_model.objects.get(username="u1")
|
||||
task = Item.objects.filter(created_by=u1).first()
|
||||
task = Task.objects.filter(created_by=u1).first()
|
||||
task.assigned_to = u1
|
||||
task.save()
|
||||
send_notify_mail(task)
|
||||
|
@ -80,7 +80,7 @@ def test_send_email_to_thread_participants(todo_setup, django_user_model, email_
|
|||
Notification email should be sent to all three users."""
|
||||
|
||||
u1 = django_user_model.objects.get(username="u1")
|
||||
task = Item.objects.filter(created_by=u1).first()
|
||||
task = Task.objects.filter(created_by=u1).first()
|
||||
|
||||
u3 = django_user_model.objects.create_user(username="u3", password="zzz", email="u3@example.com")
|
||||
u4 = django_user_model.objects.create_user(username="u4", password="zzz", email="u4@example.com")
|
||||
|
|
|
@ -3,7 +3,7 @@ import pytest
|
|||
from django.contrib.auth.models import Group
|
||||
from django.urls import reverse
|
||||
|
||||
from todo.models import Item, TaskList
|
||||
from todo.models import Task, TaskList
|
||||
|
||||
"""
|
||||
First the "smoketests" - do they respond at all for a logged in admin user?
|
||||
|
@ -15,7 +15,7 @@ After that, view contents and behaviors.
|
|||
|
||||
@pytest.mark.django_db
|
||||
def test_todo_setup(todo_setup):
|
||||
assert Item.objects.all().count() == 6
|
||||
assert Task.objects.all().count() == 6
|
||||
|
||||
|
||||
def test_view_list_lists(todo_setup, admin_client):
|
||||
|
@ -73,7 +73,7 @@ def test_view_add_list(todo_setup, admin_client):
|
|||
|
||||
|
||||
def test_view_task_detail(todo_setup, admin_client):
|
||||
task = Item.objects.first()
|
||||
task = Task.objects.first()
|
||||
url = reverse('todo:task_detail', kwargs={'task_id': task.id})
|
||||
response = admin_client.get(url)
|
||||
assert response.status_code == 200
|
||||
|
@ -131,7 +131,7 @@ def test_view_list_not_mine(todo_setup, client):
|
|||
|
||||
def test_view_task_mine(todo_setup, client):
|
||||
# Users can always view their own tasks
|
||||
task = Item.objects.filter(created_by__username="u1").first()
|
||||
task = Task.objects.filter(created_by__username="u1").first()
|
||||
client.login(username="u1", password="password")
|
||||
url = reverse('todo:task_detail', kwargs={'task_id': task.id})
|
||||
response = client.get(url)
|
||||
|
@ -147,7 +147,7 @@ def test_view_task_my_group(todo_setup, client, django_user_model):
|
|||
u2.groups.add(g1)
|
||||
|
||||
# Now u2 should be able to view one of u1's tasks.
|
||||
task = Item.objects.filter(created_by__username="u1").first()
|
||||
task = Task.objects.filter(created_by__username="u1").first()
|
||||
url = reverse('todo:task_detail', kwargs={'task_id': task.id})
|
||||
client.login(username="u2", password="password")
|
||||
response = client.get(url)
|
||||
|
@ -157,7 +157,7 @@ def test_view_task_my_group(todo_setup, client, django_user_model):
|
|||
def test_view_task_not_in_my_group(todo_setup, client):
|
||||
# User canNOT view a task that isn't theirs if the two users are not in a shared group.
|
||||
# For this we can use the fixture data as-is.
|
||||
task = Item.objects.filter(created_by__username="u1").first()
|
||||
task = Task.objects.filter(created_by__username="u1").first()
|
||||
url = reverse('todo:task_detail', kwargs={'task_id': task.id})
|
||||
client.login(username="u2", password="password")
|
||||
response = client.get(url)
|
||||
|
|
|
@ -4,35 +4,35 @@ from django.contrib.sites.models import Site
|
|||
from django.core.mail import send_mail
|
||||
from django.template.loader import render_to_string
|
||||
|
||||
from todo.models import Item, Comment
|
||||
from todo.models import Task, Comment
|
||||
|
||||
|
||||
def toggle_done(item_ids):
|
||||
"""Check for items in the mark_done POST array. If present, change status to complete.
|
||||
def toggle_done(task_ids):
|
||||
"""Check for tasks in the mark_done POST array. If present, change status to complete.
|
||||
Takes a list of task IDs. Returns list of status change strings.
|
||||
"""
|
||||
|
||||
_ret = []
|
||||
for item_id in item_ids:
|
||||
i = Item.objects.get(id=item_id)
|
||||
for task_id in task_ids:
|
||||
i = Task.objects.get(id=task_id)
|
||||
old_state = "completed" if i.completed else "incomplete"
|
||||
i.completed = not i.completed # Invert the done state, either way
|
||||
new_state = "completed" if i.completed else "incomplete"
|
||||
i.completed_date = datetime.datetime.now()
|
||||
i.save()
|
||||
_ret.append("Item \"{i}\" changed from {o} to {n}.".format(i=i.title, o=old_state, n=new_state))
|
||||
_ret.append("Task \"{i}\" changed from {o} to {n}.".format(i=i.title, o=old_state, n=new_state))
|
||||
|
||||
return _ret
|
||||
|
||||
|
||||
def toggle_deleted(deleted_item_ids):
|
||||
"""Delete selected items. Returns list of status change strings.
|
||||
def toggle_deleted(deleted_task_ids):
|
||||
"""Delete selected tasks. Returns list of status change strings.
|
||||
"""
|
||||
|
||||
_ret = []
|
||||
for item_id in deleted_item_ids:
|
||||
i = Item.objects.get(id=item_id)
|
||||
_ret.append("Item \"{i}\" deleted.".format(i=i.title))
|
||||
for task_id in deleted_task_ids:
|
||||
i = Task.objects.get(id=task_id)
|
||||
_ret.append("Task \"{i}\" deleted.".format(i=i.title))
|
||||
i.delete()
|
||||
|
||||
return _ret
|
||||
|
|
104
todo/views.py
104
todo/views.py
|
@ -14,8 +14,8 @@ from django.shortcuts import get_object_or_404, render, redirect
|
|||
from django.template.loader import render_to_string
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
|
||||
from todo.forms import AddTaskListForm, AddEditItemForm, AddExternalItemForm, SearchForm
|
||||
from todo.models import Item, TaskList, Comment
|
||||
from todo.forms import AddTaskListForm, AddEditTaskForm, AddExternalTaskForm, SearchForm
|
||||
from todo.models import Task, TaskList, Comment
|
||||
from todo.utils import (
|
||||
toggle_done,
|
||||
toggle_deleted,
|
||||
|
@ -62,16 +62,16 @@ def list_lists(request) -> HttpResponse:
|
|||
|
||||
# superusers see all lists, so count shouldn't filter by just lists the admin belongs to
|
||||
if request.user.is_superuser:
|
||||
item_count = Item.objects.filter(completed=0).count()
|
||||
task_count = Task.objects.filter(completed=0).count()
|
||||
else:
|
||||
item_count = Item.objects.filter(completed=0).filter(task_list__group__in=request.user.groups.all()).count()
|
||||
task_count = Task.objects.filter(completed=0).filter(task_list__group__in=request.user.groups.all()).count()
|
||||
|
||||
context = {
|
||||
"lists": lists,
|
||||
"thedate": thedate,
|
||||
"searchform": searchform,
|
||||
"list_count": list_count,
|
||||
"item_count": item_count,
|
||||
"task_count": task_count,
|
||||
}
|
||||
|
||||
return render(request, 'todo/list_lists.html', context)
|
||||
|
@ -95,15 +95,15 @@ def del_list(request, list_id: int, list_slug: str) -> HttpResponse:
|
|||
messages.success(request, "{list_name} is gone.".format(list_name=task_list.name))
|
||||
return redirect('todo:lists')
|
||||
else:
|
||||
item_count_done = Item.objects.filter(task_list=task_list.id, completed=True).count()
|
||||
item_count_undone = Item.objects.filter(task_list=task_list.id, completed=False).count()
|
||||
item_count_total = Item.objects.filter(task_list=task_list.id).count()
|
||||
task_count_done = Task.objects.filter(task_list=task_list.id, completed=True).count()
|
||||
task_count_undone = Task.objects.filter(task_list=task_list.id, completed=False).count()
|
||||
task_count_total = Task.objects.filter(task_list=task_list.id).count()
|
||||
|
||||
context = {
|
||||
"task_list": task_list,
|
||||
"item_count_done": item_count_done,
|
||||
"item_count_undone": item_count_undone,
|
||||
"item_count_total": item_count_total,
|
||||
"task_count_done": task_count_done,
|
||||
"task_count_undone": task_count_undone,
|
||||
"task_count_total": task_count_total,
|
||||
}
|
||||
|
||||
return render(request, 'todo/del_list.html', context)
|
||||
|
@ -111,37 +111,37 @@ def del_list(request, list_id: int, list_slug: str) -> HttpResponse:
|
|||
|
||||
@login_required
|
||||
def list_detail(request, list_id=None, list_slug=None, view_completed=False):
|
||||
"""Display and manage items in a todo list.
|
||||
"""Display and manage tasks in a todo list.
|
||||
"""
|
||||
|
||||
# Defaults
|
||||
task_list = None
|
||||
form = None
|
||||
|
||||
# Which items to show on this list view?
|
||||
# Which tasks to show on this list view?
|
||||
if list_slug == "mine":
|
||||
items = Item.objects.filter(assigned_to=request.user)
|
||||
tasks =Task.objects.filter(assigned_to=request.user)
|
||||
|
||||
else:
|
||||
# Show a specific list, ensuring permissions.
|
||||
task_list = get_object_or_404(TaskList, id=list_id)
|
||||
if task_list.group not in request.user.groups.all() and not request.user.is_staff:
|
||||
raise PermissionDenied
|
||||
items = Item.objects.filter(task_list=task_list.id)
|
||||
tasks = Task.objects.filter(task_list=task_list.id)
|
||||
|
||||
# Additional filtering
|
||||
if view_completed:
|
||||
items = items.filter(completed=True)
|
||||
tasks = tasks.filter(completed=True)
|
||||
else:
|
||||
items = items.filter(completed=False)
|
||||
tasks = tasks.filter(completed=False)
|
||||
|
||||
if request.POST:
|
||||
# Process completed and deleted items on each POST
|
||||
# Process completed and deleted tasks on each POST
|
||||
results_changed = toggle_done(request.POST.getlist('toggle_done_tasks'))
|
||||
for res in results_changed:
|
||||
messages.success(request, res)
|
||||
|
||||
results_changed = toggle_deleted(request, request.POST.getlist('toggle_deleted_tasks'))
|
||||
results_changed = toggle_deleted(request.POST.getlist('toggle_deleted_tasks'))
|
||||
for res in results_changed:
|
||||
messages.success(request, res)
|
||||
|
||||
|
@ -150,7 +150,7 @@ def list_detail(request, list_id=None, list_slug=None, view_completed=False):
|
|||
# ######################
|
||||
|
||||
if request.POST.getlist('add_edit_task'):
|
||||
form = AddEditItemForm(request.user, request.POST, initial={
|
||||
form = AddEditTaskForm(request.user, request.POST, initial={
|
||||
'assigned_to': request.user.id,
|
||||
'priority': 999,
|
||||
'task_list': task_list
|
||||
|
@ -168,7 +168,7 @@ def list_detail(request, list_id=None, list_slug=None, view_completed=False):
|
|||
else:
|
||||
# Don't allow adding new tasks on some views
|
||||
if list_slug not in ["mine", "recent-add", "recent-complete", ]:
|
||||
form = AddEditItemForm(request.user, initial={
|
||||
form = AddEditTaskForm(request.user, initial={
|
||||
'assigned_to': request.user.id,
|
||||
'priority': 999,
|
||||
'task_list': task_list
|
||||
|
@ -179,7 +179,7 @@ def list_detail(request, list_id=None, list_slug=None, view_completed=False):
|
|||
"list_slug": list_slug,
|
||||
"task_list": task_list,
|
||||
"form": form,
|
||||
"items": items,
|
||||
"tasks": tasks,
|
||||
"view_completed": view_completed,
|
||||
}
|
||||
|
||||
|
@ -191,10 +191,10 @@ def task_detail(request, task_id: int) -> HttpResponse:
|
|||
"""View task details. Allow task details to be edited. Process new comments on task.
|
||||
"""
|
||||
|
||||
task = get_object_or_404(Item, pk=task_id)
|
||||
task = get_object_or_404(Task, pk=task_id)
|
||||
comment_list = Comment.objects.filter(task=task_id)
|
||||
|
||||
# Ensure user has permission to view item. Admins can view all tasks.
|
||||
# Ensure user has permission to view task. Admins can view all tasks.
|
||||
# Get the group this task belongs to, and check whether current user is a member of that group.
|
||||
if task.task_list.group not in request.user.groups.all() and not request.user.is_staff:
|
||||
raise PermissionDenied
|
||||
|
@ -212,14 +212,14 @@ def task_detail(request, task_id: int) -> HttpResponse:
|
|||
|
||||
# Save task edits
|
||||
if request.POST.get('add_edit_task'):
|
||||
form = AddEditItemForm(request.user, request.POST, instance=task, initial={'task_list': task.task_list})
|
||||
form = AddEditTaskForm(request.user, request.POST, instance=task, initial={'task_list': task.task_list})
|
||||
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
messages.success(request, "The task has been edited.")
|
||||
return redirect('todo:list_detail', list_id=task.task_list.id, list_slug=task.task_list.slug)
|
||||
else:
|
||||
form = AddEditItemForm(request.user, instance=task, initial={'task_list': task.task_list})
|
||||
form = AddEditTaskForm(request.user, instance=task, initial={'task_list': task.task_list})
|
||||
|
||||
# Mark complete
|
||||
if request.POST.get('toggle_done'):
|
||||
|
@ -251,15 +251,15 @@ def reorder_tasks(request) -> HttpResponse:
|
|||
"""
|
||||
newtasklist = request.POST.getlist('tasktable[]')
|
||||
if newtasklist:
|
||||
# First item in received list is always empty - remove it
|
||||
# First task in received list is always empty - remove it
|
||||
del newtasklist[0]
|
||||
|
||||
# Re-prioritize each item in list
|
||||
# Re-prioritize each task in list
|
||||
i = 1
|
||||
for t in newtasklist:
|
||||
newitem = Item.objects.get(pk=t)
|
||||
newitem.priority = i
|
||||
newitem.save()
|
||||
newtask = Task.objects.get(pk=t)
|
||||
newtask.priority = i
|
||||
newtask.save()
|
||||
i += 1
|
||||
|
||||
# All views must return an httpresponse of some kind ... without this we get
|
||||
|
@ -306,33 +306,33 @@ def search(request) -> HttpResponse:
|
|||
if request.GET:
|
||||
|
||||
query_string = ''
|
||||
found_items = None
|
||||
found_tasks = None
|
||||
if ('q' in request.GET) and request.GET['q'].strip():
|
||||
query_string = request.GET['q']
|
||||
|
||||
found_items = Item.objects.filter(
|
||||
found_tasks = Task.objects.filter(
|
||||
Q(title__icontains=query_string) |
|
||||
Q(note__icontains=query_string)
|
||||
)
|
||||
else:
|
||||
# What if they selected the "completed" toggle but didn't enter a query string?
|
||||
# We still need found_items in a queryset so it can be "excluded" below.
|
||||
found_items = Item.objects.all()
|
||||
# We still need found_tasks in a queryset so it can be "excluded" below.
|
||||
found_tasks = Task.objects.all()
|
||||
|
||||
if 'inc_complete' in request.GET:
|
||||
found_items = found_items.exclude(completed=True)
|
||||
found_tasks = found_tasks.exclude(completed=True)
|
||||
|
||||
else:
|
||||
query_string = None
|
||||
found_items = None
|
||||
found_tasks =None
|
||||
|
||||
# Only include items that are in groups of which this user is a member:
|
||||
# Only include tasks that are in groups of which this user is a member:
|
||||
if not request.user.is_superuser:
|
||||
found_items = found_items.filter(task_list__group__in=request.user.groups.all())
|
||||
found_tasks = found_tasks.filter(task_list__group__in=request.user.groups.all())
|
||||
|
||||
context = {
|
||||
'query_string': query_string,
|
||||
'found_items': found_items
|
||||
'found_tasks': found_tasks
|
||||
}
|
||||
return render(request, 'todo/search_results.html', context)
|
||||
|
||||
|
@ -353,25 +353,25 @@ def external_add(request) -> HttpResponse:
|
|||
raise RuntimeError("There is no TaskList with ID specified for DEFAULT_LIST_ID in settings.")
|
||||
|
||||
if request.POST:
|
||||
form = AddExternalItemForm(request.POST)
|
||||
form = AddExternalTaskForm(request.POST)
|
||||
|
||||
if form.is_valid():
|
||||
current_site = Site.objects.get_current()
|
||||
item = form.save(commit=False)
|
||||
item.task_list = TaskList.objects.get(id=settings.TODO_DEFAULT_LIST_ID)
|
||||
item.created_by = request.user
|
||||
task = form.save(commit=False)
|
||||
task.task_list = TaskList.objects.get(id=settings.TODO_DEFAULT_LIST_ID)
|
||||
task.created_by = request.user
|
||||
if settings.TODO_DEFAULT_ASSIGNEE:
|
||||
item.assigned_to = User.objects.get(username=settings.TODO_DEFAULT_ASSIGNEE)
|
||||
item.save()
|
||||
task.assigned_to = User.objects.get(username=settings.TODO_DEFAULT_ASSIGNEE)
|
||||
task.save()
|
||||
|
||||
# Send email to assignee if we have one
|
||||
if item.assigned_to:
|
||||
email_subject = render_to_string("todo/email/assigned_subject.txt", {'task': item.title})
|
||||
email_body = render_to_string("todo/email/assigned_body.txt", {'task': item, 'site': current_site, })
|
||||
if task.assigned_to:
|
||||
email_subject = render_to_string("todo/email/assigned_subject.txt", {'task': task.title})
|
||||
email_body = render_to_string("todo/email/assigned_body.txt", {'task': task, 'site': current_site, })
|
||||
try:
|
||||
send_mail(
|
||||
email_subject, email_body, item.created_by.email,
|
||||
[item.assigned_to.email, ], fail_silently=False)
|
||||
email_subject, email_body, task.created_by.email,
|
||||
[task.assigned_to.email, ], fail_silently=False)
|
||||
except ConnectionRefusedError:
|
||||
messages.error(request, "Task saved but mail not sent. Contact your administrator.")
|
||||
|
||||
|
@ -380,7 +380,7 @@ def external_add(request) -> HttpResponse:
|
|||
return redirect(settings.TODO_PUBLIC_SUBMIT_REDIRECT)
|
||||
|
||||
else:
|
||||
form = AddExternalItemForm(initial={'priority': 999})
|
||||
form = AddExternalTaskForm(initial={'priority': 999})
|
||||
|
||||
context = {
|
||||
"form": form,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue