Rename List model to TaskList

This commit is contained in:
Scot Hacker 2018-02-10 00:25:28 -08:00
parent 774cd3d057
commit efc2dbe11a
10 changed files with 130 additions and 90 deletions

View file

@ -1,10 +1,10 @@
from django.contrib import admin from django.contrib import admin
from todo.models import Item, List, Comment from todo.models import Item, TaskList, Comment
class ItemAdmin(admin.ModelAdmin): class ItemAdmin(admin.ModelAdmin):
list_display = ('title', 'list', 'priority', 'due_date') list_display = ('title', 'task_list', 'completed', 'priority', 'due_date')
list_filter = ('list',) list_filter = ('task_list',)
ordering = ('priority',) ordering = ('priority',)
search_fields = ('name',) search_fields = ('name',)
@ -13,6 +13,6 @@ class CommentAdmin(admin.ModelAdmin):
list_display = ('author', 'date', 'snippet') list_display = ('author', 'date', 'snippet')
admin.site.register(List) admin.site.register(TaskList)
admin.site.register(Comment, CommentAdmin) admin.site.register(Comment, CommentAdmin)
admin.site.register(Item, ItemAdmin) admin.site.register(Item, ItemAdmin)

View file

@ -1,20 +1,20 @@
from django import forms from django import forms
from django.forms import ModelForm from django.forms import ModelForm
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from todo.models import Item, List from todo.models import Item, TaskList
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
class AddListForm(ModelForm): class AddTaskListForm(ModelForm):
# The picklist showing allowable groups to which a new list can be added # The picklist showing allowable groups to which a new list can be added
# determines which groups the user belongs to. This queries the form object # determines which groups the user belongs to. This queries the form object
# to derive that list. # to derive that list.
def __init__(self, user, *args, **kwargs): def __init__(self, user, *args, **kwargs):
super(AddListForm, self).__init__(*args, **kwargs) super(AddTaskListForm, self).__init__(*args, **kwargs)
self.fields['group'].queryset = Group.objects.filter(user=user) self.fields['group'].queryset = Group.objects.filter(user=user)
class Meta: class Meta:
model = List model = TaskList
exclude = [] exclude = []
@ -23,19 +23,21 @@ class AddItemForm(ModelForm):
# must find other members of the groups the current list belongs to. # must find other members of the groups the current list belongs to.
def __init__(self, task_list, *args, **kwargs): def __init__(self, task_list, *args, **kwargs):
super(AddItemForm, self).__init__(*args, **kwargs) super(AddItemForm, self).__init__(*args, **kwargs)
# print dir(self.fields['list']) # debug:
# print self.fields['list'].initial # print(dir(self.fields['list']))
# print(self.fields['list'].initial)
self.fields['assigned_to'].queryset = get_user_model().objects.filter(groups__in=[task_list.group]) self.fields['assigned_to'].queryset = get_user_model().objects.filter(groups__in=[task_list.group])
self.fields['assigned_to'].label_from_instance = \ self.fields['assigned_to'].label_from_instance = \
lambda obj: "%s (%s)" % (obj.get_full_name(), obj.username) lambda obj: "%s (%s)" % (obj.get_full_name(), obj.username)
due_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}), required=False) due_date = forms.DateField(
widget=forms.DateInput(attrs={'type': 'date'}), required=False)
title = forms.CharField( title = forms.CharField(
widget=forms.widgets.TextInput(attrs={'size': 35}) widget=forms.widgets.TextInput(attrs={'size': 35}))
)
note = forms.CharField(widget=forms.Textarea(), required=False) note = forms.CharField(
widget=forms.Textarea(), required=False)
class Meta: class Meta:
model = Item model = Item
@ -47,7 +49,7 @@ class EditItemForm(ModelForm):
# must find other members of the groups the current list belongs to. # must find other members of the groups the current list belongs to.
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(EditItemForm, self).__init__(*args, **kwargs) super(EditItemForm, self).__init__(*args, **kwargs)
self.fields['assigned_to'].queryset = get_user_model().objects.filter(groups__in=[self.instance.list.group]) self.fields['assigned_to'].queryset = get_user_model().objects.filter(groups__in=[self.instance.task_list.group])
due_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}), required=False) due_date = forms.DateField(widget=forms.DateInput(attrs={'type': 'date'}), required=False)

View file

@ -0,0 +1,52 @@
# Generated by Django 2.0.2 on 2018-02-09 23:15
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('auth', '0009_alter_user_last_name_max_length'),
('todo', '0003_assignee_optional'),
]
operations = [
migrations.CreateModel(
name='TaskList',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=60)),
('slug', models.SlugField(default='')),
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group')),
],
options={
'verbose_name_plural': 'Lists',
'ordering': ['name'],
},
),
migrations.AlterUniqueTogether(
name='list',
unique_together=set(),
),
migrations.RemoveField(
model_name='list',
name='group',
),
migrations.RemoveField(
model_name='item',
name='list',
),
migrations.DeleteModel(
name='List',
),
migrations.AddField(
model_name='item',
name='task_list',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='todo.TaskList'),
),
migrations.AlterUniqueTogether(
name='tasklist',
unique_together={('group', 'slug')},
),
]

View file

@ -9,7 +9,7 @@ from django.conf import settings
@python_2_unicode_compatible @python_2_unicode_compatible
class List(models.Model): class TaskList(models.Model):
name = models.CharField(max_length=60) name = models.CharField(max_length=60)
slug = models.SlugField(default='',) slug = models.SlugField(default='',)
group = models.ForeignKey(Group, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE)
@ -19,11 +19,11 @@ class List(models.Model):
def list_detail(self): def list_detail(self):
# Count all incomplete tasks on the current list instance # Count all incomplete tasks on the current list instance
return Item.objects.filter(list=self, completed=0) return Item.objects.filter(task_list=self, completed=0)
class Meta: class Meta:
ordering = ["name"] ordering = ["name"]
verbose_name_plural = "Lists" verbose_name_plural = "Task Lists"
# Prevents (at the database level) creation of two lists with the same name in the same group # Prevents (at the database level) creation of two lists with the same name in the same group
unique_together = ("group", "slug") unique_together = ("group", "slug")
@ -32,7 +32,7 @@ class List(models.Model):
@python_2_unicode_compatible @python_2_unicode_compatible
class Item(models.Model): class Item(models.Model):
title = models.CharField(max_length=140) title = models.CharField(max_length=140)
list = models.ForeignKey(List, on_delete=models.CASCADE) task_list = models.ForeignKey(TaskList, on_delete=models.CASCADE, null=True)
created_date = models.DateField(auto_now=True) created_date = models.DateField(auto_now=True)
due_date = models.DateField(blank=True, null=True, ) due_date = models.DateField(blank=True, null=True, )
completed = models.BooleanField(default=None) completed = models.BooleanField(default=None)

View file

@ -1,11 +1,11 @@
{% extends "todo/base.html" %} {% extends "todo/base.html" %}
{% block title %}{{ list_title }} to-do items{% endblock %} {% block title %}Delete list{% endblock %}
{% block content %} {% block content %}
{% if user.is_staff %} {% if user.is_staff %}
<h1>Delete entire list: {{ list.name }} ?</h1> <h1>Delete entire list: {{ task_list.name }} ?</h1>
<p>Category tally:</p> <p>Category tally:</p>
@ -19,11 +19,11 @@
<form action="" method="post" accept-charset="utf-8"> <form action="" method="post" accept-charset="utf-8">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="list" value="{{ list.id }}" id="some_name"> <input type="hidden" name="task_list" value="{{ task_list.id }}">
<p><input type="submit" name="delete-confirm" value="Do it! &rarr;" class="todo-button"> </p> <p><input type="submit" name="delete-confirm" value="Do it! &rarr;" class="todo-button"> </p>
</form> </form>
<a href="{% url 'todo:list_detail' list.id list_slug %}">Return to list: {{ list.name }}</a> <a href="{% url 'todo:list_detail' task_list.id task_list.slug %}">Return to list: {{ task_list.name }}</a>
{% else %} {% else %}
<p>Sorry, you don't have permission to delete lists. Please contact your group administrator.</p> <p>Sorry, you don't have permission to delete lists. Please contact your group administrator.</p>

View file

@ -1,6 +1,6 @@
Dear {{ task.assigned_to.first_name }} - Dear {{ task.assigned_to.first_name }} -
A new task on the list {{ task.list.name }} has been assigned to you by {{ task.created_by.first_name }} {{ task.created_by.last_name }}: A new task on the list {{ task.task_list.name }} has been assigned to you by {{ task.created_by.first_name }} {{ task.created_by.last_name }}:
{{ task.title }} {{ task.title }}
@ -16,5 +16,5 @@ Note: {{ task.note }}
Task details/comments: Task details/comments:
http://{{ site }}{% url 'todo:task_detail' task.id %} http://{{ site }}{% url 'todo:task_detail' task.id %}
List {{ task.list.name }}: List {{ task.task_list.name }}:
http://{{ site }}{% url 'todo:list_detail' task.list.id task.list.slug %} http://{{ site }}{% url 'todo:list_detail' task.task_list.id task.task_list.slug %}

View file

@ -11,6 +11,6 @@ Comment:
Task details/comments: Task details/comments:
https://{{ site }}{% url 'todo:task_detail' task.id %} https://{{ site }}{% url 'todo:task_detail' task.id %}
List {{ task.list.name }}: List {{ task.task_list.name }}:
https://{{ site }}{% url 'todo:list_detail' task.list.id task.list.slug %} https://{{ site }}{% url 'todo:list_detail' task.task_list.id task.task_list.slug %}

View file

@ -13,8 +13,15 @@
{% for f in found_items %} {% for f in found_items %}
<p><strong><a href="{% url 'todo:task_detail' f.id %}">{{ f.title }}</a></strong><br /> <p><strong><a href="{% url 'todo:task_detail' f.id %}">{{ f.title }}</a></strong><br />
<span class="minor"> <span class="minor">
On list: <a href="{% url 'todo:list_detail' f.list.id f.list.slug %}">{{ f.list.name }}</a><br /> In list:
Assigned to: {% if f.assigned_to %}{{ f.assigned_to }}{% else %}Anyone{% endif %} (created by: {{ f.created_by }})<br /> <a href="{% url 'todo:list_detail' f.task_list.id f.task_list.slug %}">
{{ f.task_list.name }}
</a>
<br />
Assigned to:
{% if f.assigned_to %}{{ f.assigned_to }}{% else %}Anyone{% endif %}
(created by: {{ f.created_by }})
<br />
Complete: {{ f.completed|yesno:"Yes,No" }} Complete: {{ f.completed|yesno:"Yes,No" }}
</span> </span>
</p> </p>

View file

@ -26,7 +26,7 @@
<p id="slideToggle" ><strong>&rarr; Click to edit details &larr;</strong></p> <p id="slideToggle" ><strong>&rarr; Click to edit details &larr;</strong></p>
<p> <p>
<strong>In list:</strong> <a href="{% url 'todo:list_detail' task.list.id task.list.slug %}" class="showlink">{{ task.list }}</a><br /> <strong>In list:</strong> <a href="{% url 'todo:list_detail' task.task_list.id task.task_list.slug %}" class="showlink">{{ task.list }}</a><br />
<strong>Assigned to:</strong> {% if task.assigned_to %}{{ task.assigned_to.get_full_name }}{% else %}Anyone{% endif %}<br /> <strong>Assigned to:</strong> {% if task.assigned_to %}{{ task.assigned_to.get_full_name }}{% else %}Anyone{% endif %}<br />
<strong>Created by:</strong> {{ task.created_by.first_name }} {{ task.created_by.last_name }}<br /> <strong>Created by:</strong> {{ task.created_by.first_name }} {{ task.created_by.last_name }}<br />
<strong>Due date:</strong> {{ task.due_date }}<br /> <strong>Due date:</strong> {{ task.due_date }}<br />
@ -48,7 +48,7 @@
<tr> <tr>
<td>List:</td> <td>List:</td>
<td>{{ form.list }} </td> <td>{{ form.task_list }} </td>
</tr> </tr>
<tr> <tr>

View file

@ -14,9 +14,9 @@ from django.urls import reverse
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
from todo import settings from todo import settings
from todo.forms import AddListForm, AddItemForm, EditItemForm, AddExternalItemForm, SearchForm from todo.forms import AddTaskListForm, AddItemForm, EditItemForm, AddExternalItemForm, SearchForm
from todo.models import Item, List, Comment from todo.models import Item, TaskList, Comment
from todo.utils import mark_done, undo_completed_task, del_tasks, send_notify_mail from todo.utils import toggle_done, toggle_deleted, send_notify_mail
def check_user_allowed(user): def check_user_allowed(user):
@ -43,9 +43,9 @@ def list_lists(request):
# Superusers see all lists # Superusers see all lists
if request.user.is_superuser: if request.user.is_superuser:
list_list = List.objects.all().order_by('group', 'name') list_list = TaskList.objects.all().order_by('group', 'name')
else: else:
list_list = List.objects.filter(group__in=request.user.groups.all()).order_by('group', 'name') list_list = TaskList.objects.filter(group__in=request.user.groups.all()).order_by('group', 'name')
list_count = list_list.count() list_count = list_list.count()
@ -53,7 +53,7 @@ def list_lists(request):
if request.user.is_superuser: if request.user.is_superuser:
item_count = Item.objects.filter(completed=0).count() item_count = Item.objects.filter(completed=0).count()
else: else:
item_count = Item.objects.filter(completed=0).filter(list__group__in=request.user.groups.all()).count() item_count = Item.objects.filter(completed=0).filter(task_list__group__in=request.user.groups.all()).count()
return render(request, 'todo/list_lists.html', locals()) return render(request, 'todo/list_lists.html', locals())
@ -62,68 +62,47 @@ def list_lists(request):
def del_list(request, list_id, list_slug): def del_list(request, list_id, list_slug):
"""Delete an entire list. Danger Will Robinson! Only staff members should be allowed to access this view. """Delete an entire list. Danger Will Robinson! Only staff members should be allowed to access this view.
""" """
list = get_object_or_404(List, slug=list_slug) task_list = get_object_or_404(TaskList, slug=list_slug)
if request.method == 'POST': if request.method == 'POST':
List.objects.get(id=list.id).delete() TaskList.objects.get(id=task_list.id).delete()
messages.success(request, "{list_name} is gone.".format(list_name=list.name)) messages.success(request, "{list_name} is gone.".format(list_name=task_list.name))
return redirect('todo:lists') return redirect('todo:lists')
else: else:
item_count_done = Item.objects.filter(list=list.id, completed=1).count() item_count_done = Item.objects.filter(task_list=task_list.id, completed=True).count()
item_count_undone = Item.objects.filter(list=list.id, completed=0).count() item_count_undone = Item.objects.filter(task_list=task_list.id, completed=False).count()
item_count_total = Item.objects.filter(list=list.id).count() item_count_total = Item.objects.filter(task_list=task_list.id).count()
return render(request, 'todo/del_list.html', locals()) return render(request, 'todo/del_list.html', locals())
@user_passes_test(check_user_allowed)
def list_detail(request, list_id=None, list_slug=None, view_completed=False): def list_detail(request, list_id=None, list_slug=None, view_completed=False):
"""Display and manage items in a list. """Display and manage items in a todo list.
""" """
# Make sure the accessing user has permission to view this list. if request.POST:
# Always authorize the "mine" view. Admins can view/edit all lists. # Process completed and deleted requests on each POST
if list_slug == "mine" or list_slug == "recent-add" or list_slug == "recent-complete": toggle_done(request, request.POST.getlist('toggle_done_tasks'))
auth_ok = True toggle_deleted(request, request.POST.getlist('toggle_deleted_tasks'))
else:
list = get_object_or_404(List, id=list_id)
if list.group in request.user.groups.all() or request.user.is_staff or list_slug == "mine":
auth_ok = True
else: # User does not belong to the group this list is attached to
messages.error(request, "You do not have permission to view/edit this list.")
# Process all possible list interactions on each submit
mark_done(request, request.POST.getlist('mark_done'))
del_tasks(request, request.POST.getlist('del_tasks'))
undo_completed_task(request, request.POST.getlist('undo_completed_task'))
thedate = datetime.datetime.now()
created_date = "%s-%s-%s" % (thedate.year, thedate.month, thedate.day)
# Get set of items with this list ID, or filter on items assigned to me, or recently added/completed
if list_slug == "mine": if list_slug == "mine":
task_list = Item.objects.filter(assigned_to=request.user, completed=False) items = Item.objects.filter(assigned_to=request.user)
completed_list = Item.objects.filter(assigned_to=request.user, completed=True)
elif list_slug == "recent-add":
# Only show items in lists that are in groups that the current user is also in.
# Assume this only includes uncompleted items.
task_list = Item.objects.filter(
list__group__in=(request.user.groups.all()),
completed=False).order_by('-created_date')[:50]
elif list_slug == "recent-complete":
# Only show items in lists that are in groups that the current user is also in.
task_list = Item.objects.filter(
list__group__in=request.user.groups.all(),
completed=True).order_by('-completed_date')[:50]
else: else:
task_list = Item.objects.filter(list=list.id, completed=0) task_list = get_object_or_404(TaskList, id=list_id)
completed_list = Item.objects.filter(list=list.id, completed=1) items = Item.objects.filter(task_list=task_list.id)
# Apply filters to base queryset
if view_completed:
items = items.filter(completed=True)
else:
items = items.filter(completed=False)
# ######################
# Add New Task Form
# ######################
if request.POST.getlist('add_task'): if request.POST.getlist('add_task'):
form = AddItemForm(list, request.POST, initial={ form = AddItemForm(task_list, request.POST, initial={
'assigned_to': request.user.id, 'assigned_to': request.user.id,
'priority': 999, 'priority': 999,
}) })
@ -140,7 +119,7 @@ def list_detail(request, list_id=None, list_slug=None, view_completed=False):
else: else:
# Don't allow adding new tasks on some views # Don't allow adding new tasks on some views
if list_slug != "mine" and list_slug != "recent-add" and list_slug != "recent-complete": if list_slug != "mine" and list_slug != "recent-add" and list_slug != "recent-complete":
form = AddItemForm(list, initial={ form = AddItemForm(task_list=task_list, initial={
'assigned_to': request.user.id, 'assigned_to': request.user.id,
'priority': 999, 'priority': 999,
}) })
@ -159,7 +138,7 @@ def task_detail(request, task_id):
# Get the group this task belongs to, and check whether current user is a member of that group. # Get the group this task belongs to, and check whether current user is a member of that group.
# Admins can edit all tasks. # Admins can edit all tasks.
if task.list.group in request.user.groups.all() or request.user.is_staff: if task.task_list.group in request.user.groups.all() or request.user.is_staff:
auth_ok = True auth_ok = True
if request.POST: if request.POST:
@ -201,7 +180,7 @@ def task_detail(request, task_id):
messages.success(request, "The task has been edited.") messages.success(request, "The task has been edited.")
return redirect('todo:list_detail', list_id=task.list.id, list_slug=task.list.slug) return redirect('todo:list_detail', list_id=task.task_list.id, list_slug=task.task_list.slug)
else: else:
form = EditItemForm(instance=task) form = EditItemForm(instance=task)
if task.due_date: if task.due_date:
@ -276,7 +255,7 @@ def add_list(request):
"""Allow users to add a new todo list to the group they're in. """Allow users to add a new todo list to the group they're in.
""" """
if request.POST: if request.POST:
form = AddListForm(request.user, request.POST) form = AddTaskListForm(request.user, request.POST)
if form.is_valid(): if form.is_valid():
try: try:
form.save() form.save()
@ -290,9 +269,9 @@ def add_list(request):
"Most likely a list with the same name in the same group already exists.") "Most likely a list with the same name in the same group already exists.")
else: else:
if request.user.groups.all().count() == 1: if request.user.groups.all().count() == 1:
form = AddListForm(request.user, initial={"group": request.user.groups.all()[0]}) form = AddTaskListForm(request.user, initial={"group": request.user.groups.all()[0]})
else: else:
form = AddListForm(request.user) form = AddTaskListForm(request.user)
return render(request, 'todo/add_list.html', locals()) return render(request, 'todo/add_list.html', locals())