From bc473375ba84a671d6a0f2087df716c44226e9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Wed, 4 Feb 2015 19:49:35 +0100 Subject: [PATCH] US #55: Custom fields - Create model --- settings/common.py | 1 + taiga/projects/custom_attributes/__init__.py | 0 .../migrations/0001_initial.py | 84 +++++++++++++++++++ .../custom_attributes/migrations/__init__.py | 0 taiga/projects/custom_attributes/models.py | 74 ++++++++++++++++ 5 files changed, 159 insertions(+) create mode 100644 taiga/projects/custom_attributes/__init__.py create mode 100644 taiga/projects/custom_attributes/migrations/0001_initial.py create mode 100644 taiga/projects/custom_attributes/migrations/__init__.py create mode 100644 taiga/projects/custom_attributes/models.py diff --git a/settings/common.py b/settings/common.py index a8ea96cd..dc8d2b9d 100644 --- a/settings/common.py +++ b/settings/common.py @@ -180,6 +180,7 @@ INSTALLED_APPS = [ "taiga.userstorage", "taiga.projects", "taiga.projects.references", + "taiga.projects.custom_attributes", "taiga.projects.history", "taiga.projects.notifications", "taiga.projects.attachments", diff --git a/taiga/projects/custom_attributes/__init__.py b/taiga/projects/custom_attributes/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/taiga/projects/custom_attributes/migrations/0001_initial.py b/taiga/projects/custom_attributes/migrations/0001_initial.py new file mode 100644 index 00000000..5814507d --- /dev/null +++ b/taiga/projects/custom_attributes/migrations/0001_initial.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django.utils.timezone + + +class Migration(migrations.Migration): + + dependencies = [ + ('projects', '0015_auto_20141230_1212'), + ] + + operations = [ + migrations.CreateModel( + name='IssueCustomAttribute', + fields=[ + ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), + ('name', models.CharField(verbose_name='name', max_length=64)), + ('description', models.TextField(blank=True, verbose_name='description')), + ('order', models.IntegerField(verbose_name='order', default=10000)), + ('created_date', models.DateTimeField(verbose_name='created date', default=django.utils.timezone.now)), + ('modified_date', models.DateTimeField(verbose_name='modified date')), + ('project', models.ForeignKey(to='projects.Project', verbose_name='project', related_name='issuecustomattributes')), + ], + options={ + 'ordering': ['project', 'order', 'name'], + 'verbose_name': 'issue custom attribute', + 'verbose_name_plural': 'issue custom attributes', + 'abstract': False, + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='TaskCustomAttribute', + fields=[ + ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), + ('name', models.CharField(verbose_name='name', max_length=64)), + ('description', models.TextField(blank=True, verbose_name='description')), + ('order', models.IntegerField(verbose_name='order', default=10000)), + ('created_date', models.DateTimeField(verbose_name='created date', default=django.utils.timezone.now)), + ('modified_date', models.DateTimeField(verbose_name='modified date')), + ('project', models.ForeignKey(to='projects.Project', verbose_name='project', related_name='taskcustomattributes')), + ], + options={ + 'ordering': ['project', 'order', 'name'], + 'verbose_name': 'task custom attribute', + 'verbose_name_plural': 'task custom attributes', + 'abstract': False, + }, + bases=(models.Model,), + ), + migrations.CreateModel( + name='UserStoryCustomAttribute', + fields=[ + ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)), + ('name', models.CharField(verbose_name='name', max_length=64)), + ('description', models.TextField(blank=True, verbose_name='description')), + ('order', models.IntegerField(verbose_name='order', default=10000)), + ('created_date', models.DateTimeField(verbose_name='created date', default=django.utils.timezone.now)), + ('modified_date', models.DateTimeField(verbose_name='modified date')), + ('project', models.ForeignKey(to='projects.Project', verbose_name='project', related_name='userstorycustomattributes')), + ], + options={ + 'ordering': ['project', 'order', 'name'], + 'verbose_name': 'user story custom attribute', + 'verbose_name_plural': 'user story custom attributes', + 'abstract': False, + }, + bases=(models.Model,), + ), + migrations.AlterUniqueTogether( + name='userstorycustomattribute', + unique_together=set([('project', 'name')]), + ), + migrations.AlterUniqueTogether( + name='taskcustomattribute', + unique_together=set([('project', 'name')]), + ), + migrations.AlterUniqueTogether( + name='issuecustomattribute', + unique_together=set([('project', 'name')]), + ), + ] diff --git a/taiga/projects/custom_attributes/migrations/__init__.py b/taiga/projects/custom_attributes/migrations/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/taiga/projects/custom_attributes/models.py b/taiga/projects/custom_attributes/models.py new file mode 100644 index 00000000..5efbea47 --- /dev/null +++ b/taiga/projects/custom_attributes/models.py @@ -0,0 +1,74 @@ +# Copyright (C) 2015 Andrey Antukh +# Copyright (C) 2015 Jesús Espino +# Copyright (C) 2015 David Barragán +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +from django.db import models +from django.utils.translation import ugettext_lazy as _ +from django.utils import timezone + + +###################################################### +# Base Model Class +####################################################### + +class AbstractCustomAttribute(models.Model): + name = models.CharField(null=False, blank=False, max_length=64, verbose_name=_("name")) + description = models.TextField(null=False, blank=True, verbose_name=_("description")) + order = models.IntegerField(null=False, blank=False, default=10000, verbose_name=_("order")) + project = models.ForeignKey("projects.Project", null=False, blank=False, related_name="%(class)ss", + verbose_name=_("project")) + + created_date = models.DateTimeField(null=False, blank=False, default=timezone.now, + verbose_name=_("created date")) + modified_date = models.DateTimeField(null=False, blank=False, + verbose_name=_("modified date")) + _importing = None + + class Meta: + abstract = True + ordering = ["project", "order", "name"] + unique_together = ("project", "name") + + def __str__(self): + return self.name + + def save(self, *args, **kwargs): + if not self._importing or not self.modified_date: + self.modified_date = timezone.now() + + return super().save(*args, **kwargs) + + + +###################################################### +# Custom Field Models +####################################################### + +class UserStoryCustomAttribute(AbstractCustomAttribute): + class Meta(AbstractCustomAttribute.Meta): + verbose_name = "user story custom attribute" + verbose_name_plural = "user story custom attributes" + + +class TaskCustomAttribute(AbstractCustomAttribute): + class Meta(AbstractCustomAttribute.Meta): + verbose_name = "task custom attribute" + verbose_name_plural = "task custom attributes" + + +class IssueCustomAttribute(AbstractCustomAttribute): + class Meta(AbstractCustomAttribute.Meta): + verbose_name = "issue custom attribute" + verbose_name_plural = "issue custom attributes"