diff options
author | Mike Crute <mcrute@gmail.com> | 2010-07-09 22:46:01 -0400 |
---|---|---|
committer | Mike Crute <mcrute@gmail.com> | 2010-07-09 22:46:01 -0400 |
commit | 970eeafc1edd7f5889cb6584be292ae9aa07b135 (patch) | |
tree | 5a158e45a8aeb745bf8d506d15144fa365f98cc4 | |
parent | 57336e9b907ac9efa02f427a8da949f46976afdd (diff) | |
download | snakeplan-970eeafc1edd7f5889cb6584be292ae9aa07b135.tar.bz2 snakeplan-970eeafc1edd7f5889cb6584be292ae9aa07b135.tar.xz snakeplan-970eeafc1edd7f5889cb6584be292ae9aa07b135.zip |
Cleaning up models and creating custom admin settings for projects.
-rw-r--r--[-rwxr-xr-x] | snakeplan/projects/__init__.py | 0 | ||||
-rw-r--r-- | snakeplan/projects/admin.py | 20 | ||||
-rw-r--r--[-rwxr-xr-x] | snakeplan/projects/models.py | 70 | ||||
-rw-r--r-- | snakeplan/projects/urls.py | 14 | ||||
-rw-r--r-- | snakeplan/projects/views/projects.py | 2 |
5 files changed, 66 insertions, 40 deletions
diff --git a/snakeplan/projects/__init__.py b/snakeplan/projects/__init__.py index e69de29..e69de29 100755..100644 --- a/snakeplan/projects/__init__.py +++ b/snakeplan/projects/__init__.py | |||
diff --git a/snakeplan/projects/admin.py b/snakeplan/projects/admin.py index 3970fb0..981e4e5 100644 --- a/snakeplan/projects/admin.py +++ b/snakeplan/projects/admin.py | |||
@@ -19,10 +19,18 @@ SnakePlan Admin Setup | |||
19 | # limitations under the License. | 19 | # limitations under the License. |
20 | 20 | ||
21 | from snakeplan.projects import models | 21 | from snakeplan.projects import models |
22 | from django.contrib import admin | 22 | from django.contrib.admin import ModelAdmin, site |
23 | 23 | ||
24 | admin.site.register(models.Task) | 24 | |
25 | admin.site.register(models.Story) | 25 | class ProjectAdmin(ModelAdmin): |
26 | admin.site.register(models.Project) | 26 | |
27 | admin.site.register(models.Iteration) | 27 | list_display = ('name', 'active') |
28 | admin.site.register(models.LoggedTime) | 28 | ordering = ('name', ) |
29 | |||
30 | |||
31 | site.register(models.Task) | ||
32 | site.register(models.Story) | ||
33 | site.register(models.Project, ProjectAdmin) | ||
34 | site.register(models.Iteration) | ||
35 | site.register(models.DevelopmentIteration) | ||
36 | site.register(models.LoggedTime) | ||
diff --git a/snakeplan/projects/models.py b/snakeplan/projects/models.py index f6a54f1..e707bb2 100755..100644 --- a/snakeplan/projects/models.py +++ b/snakeplan/projects/models.py | |||
@@ -24,8 +24,13 @@ from django.contrib.auth.models import User | |||
24 | 24 | ||
25 | 25 | ||
26 | STATUSES = ( | 26 | STATUSES = ( |
27 | (0, 'Active'), | 27 | (0, 'Draft'), |
28 | (1, 'Inactive'), | 28 | (1, 'Defined'), |
29 | (2, 'Estimated'), | ||
30 | (3, 'Planned'), | ||
31 | (4, 'Implemented'), | ||
32 | (5, 'Verified'), | ||
33 | (6, 'Accepted'), | ||
29 | ) | 34 | ) |
30 | 35 | ||
31 | DISPOSITIONS = ( | 36 | DISPOSITIONS = ( |
@@ -47,10 +52,9 @@ TASK_TYPES = ( | |||
47 | class Project(Model): | 52 | class Project(Model): |
48 | 53 | ||
49 | name = m.CharField(max_length=200) | 54 | name = m.CharField(max_length=200) |
50 | description = m.TextField(blank=True) | 55 | description = m.TextField(blank=True, null=True) |
51 | active = m.BooleanField(default=True) | 56 | active = m.BooleanField(default=True) |
52 | hidden = m.BooleanField(default=False) | 57 | wiki_link = m.URLField(blank=True, null=True) |
53 | wiki_link = m.URLField(blank=True) | ||
54 | 58 | ||
55 | def __unicode__(self): | 59 | def __unicode__(self): |
56 | return self.name | 60 | return self.name |
@@ -58,33 +62,43 @@ class Project(Model): | |||
58 | 62 | ||
59 | class Iteration(Model): | 63 | class Iteration(Model): |
60 | 64 | ||
61 | name = m.CharField(max_length=200) | ||
62 | project = m.ForeignKey(Project) | 65 | project = m.ForeignKey(Project) |
63 | status = m.IntegerField(choices=STATUSES, default=0) | 66 | |
64 | start_date = m.DateField() | 67 | name = m.CharField(max_length=200) |
65 | end_date = m.DateField() | 68 | description = m.TextField(blank=True, null=True) |
66 | days_worked = m.DecimalField(default=0, decimal_places=2, max_digits=5) | 69 | |
67 | description = m.TextField(blank=True) | 70 | # It should not be possible to delete the backlog |
71 | can_delete = m.BooleanField(default=True) | ||
68 | 72 | ||
69 | def __unicode__(self): | 73 | def __unicode__(self): |
70 | return self.name | 74 | return self.name |
71 | 75 | ||
72 | 76 | ||
77 | # Not all iterations are actually open for development | ||
78 | # for example, the Backlog is not a development iteration. | ||
79 | class DevelopmentIteration(Iteration): | ||
80 | |||
81 | active = m.BooleanField(default=True) | ||
82 | start_date = m.DateField(blank=True, null=True) | ||
83 | end_date = m.DateField(blank=True, null=True) | ||
84 | |||
85 | |||
73 | class Story(Model): | 86 | class Story(Model): |
74 | 87 | ||
75 | class Meta: | 88 | class Meta: |
76 | verbose_name_plural = 'Stories' | 89 | verbose_name_plural = 'Stories' |
77 | 90 | ||
78 | name = m.CharField(max_length=200) | ||
79 | iteration = m.ForeignKey(Iteration) | 91 | iteration = m.ForeignKey(Iteration) |
80 | disposition = m.IntegerField(choices=DISPOSITIONS) | ||
81 | customer = m.ForeignKey(User, blank=True, null=True, | ||
82 | related_name='story_customer') | ||
83 | tracker = m.ForeignKey(User, blank=True, null=True) | 92 | tracker = m.ForeignKey(User, blank=True, null=True) |
93 | customer = m.ForeignKey(User, blank=True, null=True, | ||
94 | related_name='story_customer') | ||
95 | |||
96 | name = m.CharField(max_length=200) | ||
97 | disposition = m.IntegerField(choices=DISPOSITIONS, default=0) | ||
84 | status = m.IntegerField(choices=STATUSES, default=0) | 98 | status = m.IntegerField(choices=STATUSES, default=0) |
85 | priority = m.IntegerField() | 99 | priority = m.IntegerField() |
86 | order = m.IntegerField() | 100 | order = m.IntegerField() |
87 | description = m.TextField(blank=True) | 101 | description = m.TextField(blank=True, null=True) |
88 | 102 | ||
89 | def __unicode__(self): | 103 | def __unicode__(self): |
90 | return self.name | 104 | return self.name |
@@ -92,13 +106,15 @@ class Story(Model): | |||
92 | 106 | ||
93 | class Task(Model): | 107 | class Task(Model): |
94 | 108 | ||
95 | name = m.CharField(max_length=200) | ||
96 | story = m.ForeignKey(Story) | 109 | story = m.ForeignKey(Story) |
97 | task_type = m.IntegerField(choices=TASK_TYPES) | 110 | acceptor = m.ForeignKey(User, blank=True, null=True) |
98 | disposition = m.IntegerField(choices=DISPOSITIONS) | 111 | |
99 | acceptor = m.ForeignKey(User, blank=True) | 112 | name = m.CharField(max_length=200) |
113 | completed = m.BooleanField(default=False) | ||
114 | task_type = m.IntegerField(choices=TASK_TYPES, default=0) | ||
115 | disposition = m.IntegerField(choices=DISPOSITIONS, default=0) | ||
100 | estimated_hours = m.DecimalField(decimal_places=2, max_digits=5) | 116 | estimated_hours = m.DecimalField(decimal_places=2, max_digits=5) |
101 | description = m.TextField(blank=True) | 117 | description = m.TextField(blank=True, null=True) |
102 | 118 | ||
103 | def __unicode__(self): | 119 | def __unicode__(self): |
104 | return self.name | 120 | return self.name |
@@ -106,13 +122,15 @@ class Task(Model): | |||
106 | 122 | ||
107 | class LoggedTime(Model): | 123 | class LoggedTime(Model): |
108 | 124 | ||
109 | start_time = m.DateTimeField(blank=True) | 125 | task = m.ForeignKey(Task) |
110 | end_time = m.DateTimeField(blank=True) | 126 | person1 = m.ForeignKey(User, blank=True, null=True, related_name="person1") |
127 | person2 = m.ForeignKey(User, blank=True, null=True, related_name="person2") | ||
128 | |||
111 | logged_date = m.DateField() | 129 | logged_date = m.DateField() |
130 | start_time = m.DateTimeField(blank=True, null=True) | ||
131 | end_time = m.DateTimeField(blank=True, null=True) | ||
112 | duration = m.DecimalField(decimal_places=2, max_digits=5) | 132 | duration = m.DecimalField(decimal_places=2, max_digits=5) |
113 | person1 = m.ForeignKey(User, blank=True, related_name="person1") | 133 | description = m.TextField(blank=True, null=True) |
114 | person2 = m.ForeignKey(User, blank=True, related_name="person2") | ||
115 | description = m.TextField(blank=True) | ||
116 | 134 | ||
117 | def __unicode__(self): | 135 | def __unicode__(self): |
118 | return self.description | 136 | return self.description |
diff --git a/snakeplan/projects/urls.py b/snakeplan/projects/urls.py index cc273a2..259cbc9 100644 --- a/snakeplan/projects/urls.py +++ b/snakeplan/projects/urls.py | |||
@@ -21,11 +21,11 @@ SnakePlan Project Urls | |||
21 | from django.conf.urls.defaults import patterns, url | 21 | from django.conf.urls.defaults import patterns, url |
22 | 22 | ||
23 | urlpatterns = patterns('snakeplan.projects.views', | 23 | urlpatterns = patterns('snakeplan.projects.views', |
24 | (r'^$', 'projects.index'), | 24 | url(r'^$', 'projects.index'), |
25 | (r'^projects/$', 'projects.index'), | 25 | url(r'^projects/$', 'projects.index', name='project-list'), |
26 | (r'^project/create/', 'projects.create_project'), | 26 | url(r'^project/create/', 'projects.create_project', name='create-project'), |
27 | (r'^project/(.*)/iterations/', 'projects.project_iterations'), | 27 | url(r'^project/(.*)/iterations/', 'projects.project_iterations', name='project-iterations'), |
28 | (r'^iteration/(.*)/stories/', 'iterations.index'), | 28 | url(r'^iteration/(.*)/stories/', 'iterations.index'), |
29 | (r'^story/(.*)/tasks/', 'stories.index'), | 29 | url(r'^story/(.*)/tasks/', 'stories.index'), |
30 | (r'^task/(.*)/', 'tasks.index'), | 30 | url(r'^task/(.*)/', 'tasks.index'), |
31 | ) | 31 | ) |
diff --git a/snakeplan/projects/views/projects.py b/snakeplan/projects/views/projects.py index 7cc4017..8fb68c8 100644 --- a/snakeplan/projects/views/projects.py +++ b/snakeplan/projects/views/projects.py | |||
@@ -10,7 +10,7 @@ from snakeplan.projects.forms import ProjectForm | |||
10 | def index(request): | 10 | def index(request): |
11 | return list_detail.object_list( | 11 | return list_detail.object_list( |
12 | request=request, | 12 | request=request, |
13 | queryset=Project.objects.all(), | 13 | queryset=Project.objects.order_by('-active', 'name').all(), |
14 | allow_empty=True | 14 | allow_empty=True |
15 | ) | 15 | ) |
16 | 16 | ||