diff --git a/project/admin.py b/project/admin.py index 8c38f3f..f670181 100644 --- a/project/admin.py +++ b/project/admin.py @@ -1,3 +1,20 @@ from django.contrib import admin +from orderable.admin import OrderableAdmin +from project.models import Project, DueDate, Category # Register your models here. + +class DueDateInline(admin.TabularInline): + model = DueDate + +class CategoryClass(OrderableAdmin): + list_display = ('__unicode__', 'sort_order_display') + +class ProjectAdmin(admin.ModelAdmin): + list_display = ('title','description','status') + fields = ['title','description','status'] + inlines = (DueDateInline,) + +admin.site.register(Project, ProjectAdmin) +admin.site.register(DueDate) +admin.site.register(Category, CategoryClass) \ No newline at end of file diff --git a/project/api/__init__.py b/project/api/__init__.py new file mode 100644 index 0000000..1e330b8 --- /dev/null +++ b/project/api/__init__.py @@ -0,0 +1 @@ +__author__ = 'tyrel' diff --git a/project/api/serializers.py b/project/api/serializers.py new file mode 100644 index 0000000..570f259 --- /dev/null +++ b/project/api/serializers.py @@ -0,0 +1,18 @@ +__author__ = 'tyrel' +from rest_framework import serializers +from project.models import Project, Category, DueDate + + +class ProjectSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Project + + +class CategorySerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = Category + + +class DueDateSerializer(serializers.HyperlinkedModelSerializer): + class Meta: + model = DueDate \ No newline at end of file diff --git a/project/api/viewsets.py b/project/api/viewsets.py new file mode 100644 index 0000000..044fce2 --- /dev/null +++ b/project/api/viewsets.py @@ -0,0 +1,19 @@ +__author__ = 'tyrel' +from rest_framework import viewsets +from project.models import Project, Category, DueDate +from project.api.serializers import ProjectSerializer, CategorySerializer, DueDateSerializer + + +class ProjectViewSet(viewsets.ModelViewSet): + queryset = Project.objects.all() + serializer_class = ProjectSerializer + + +class CategoryViewSet(viewsets.ModelViewSet): + queryset = Category.objects.all() + serializer_class = CategorySerializer + + +class DueDateViewSet(viewsets.ModelViewSet): + queryset = DueDate.objects.all() + serializer_class = DueDateSerializer \ No newline at end of file diff --git a/project/helpers.py b/project/helpers.py new file mode 100644 index 0000000..71951d4 --- /dev/null +++ b/project/helpers.py @@ -0,0 +1,13 @@ +__author__ = 'tyrel' +import datetime +from django.conf import settings + +def get_status(title, due_date): + overdue = "" + message = title + if due_date: + if due_date < datetime.date.today(): + overdue = " Overdue" + message += " ({}{})".format(due_date.strftime(settings.DATE_FMT), overdue) + return message + diff --git a/project/migrations/__init__.py b/project/migrations/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/project/models.py b/project/models.py index 71a8362..52fd6e2 100644 --- a/project/models.py +++ b/project/models.py @@ -1,3 +1,52 @@ from django.db import models +import datetime +from django.conf import settings +from orderable.models import Orderable -# Create your models here. +STATUSES = ( + (0, 'Upcoming'), + (1, 'Current'), + (2, 'Backlog'), + (3, 'Completed'), +) + + +class Project(models.Model): + title = models.CharField(max_length=256) + description = models.TextField(blank=True, null=True) + status = models.IntegerField(choices=STATUSES, default=0) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + +class Category(Orderable): + title = models.CharField(max_length=256) + + class Meta(Orderable.Meta): + verbose_name_plural = "Categories" + + def __unicode__(self): + return self.title + + +class DueDate(models.Model): + title = models.ForeignKey("Category") + due = models.DateField(blank=True, null=True) + completed = models.BooleanField(default=False) + project = models.ForeignKey("Project") + + def completed_overdue_date(self): + if self.completed: + return "Completed" + if not self.due: + return "" + if self.due > datetime.date.today(): + return "Overdue {}".format(self.due.strftime(settings.DATE_FMT)) + return self.due.strftime(settings.DATE_FMT) + + class Meta: + verbose_name = "Due Date" + verbose_name_plural = "Due Dates" + + def __unicode__(self): + return unicode(self.title) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 3404ad0..909e418 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ Django==1.7.6 mysqlclient djangorestframework markdown -django-filter \ No newline at end of file +django-filter +django-orderable diff --git a/roadmap/settings.py b/roadmap/settings.py index 3c204e4..5889fbb 100644 --- a/roadmap/settings.py +++ b/roadmap/settings.py @@ -15,9 +15,19 @@ INSTALLED_APPS = ( 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', - 'django.contrib.staticfiles', - 'rest_framework' + 'django.contrib.staticfiles') + +APPS = ( + 'project', ) +INSTALLED_APPS += APPS + + +THIRD_PARTY_APPS = ( + 'rest_framework', + 'orderable' +) +INSTALLED_APPS += THIRD_PARTY_APPS MIDDLEWARE_CLASSES = ( @@ -47,7 +57,7 @@ DATABASES = { } LANGUAGE_CODE = 'en-us' -TIME_ZONE = 'EST' +TIME_ZONE = 'America/New_York' USE_I18N = True USE_L10N = True USE_TZ = True @@ -61,4 +71,6 @@ TEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates'), ) -from drf_settings import * \ No newline at end of file +from drf_settings import * + +DATE_FMT = "%a %m/%d" \ No newline at end of file diff --git a/roadmap/urls.py b/roadmap/urls.py index c39100b..d2d755c 100644 --- a/roadmap/urls.py +++ b/roadmap/urls.py @@ -2,9 +2,13 @@ from django.conf.urls import patterns, include, url from django.contrib import admin from rest_framework import routers from user_api_views import UserViewSet +from project.api.viewsets import ProjectViewSet, CategoryViewSet, DueDateViewSet router = routers.DefaultRouter() router.register(r'users', UserViewSet) +router.register(r'projects', ProjectViewSet) +router.register(r'categories', CategoryViewSet) +router.register(r'due_dates', DueDateViewSet) urlpatterns = patterns('', url(r'^admin/', include(admin.site.urls)),