Adding initial version of exporter/importer

remotes/origin/enhancement/email-actions
Jesús Espino 2014-08-21 16:05:49 +02:00
parent 3b48c1fa95
commit 1e48340c48
38 changed files with 2790 additions and 35 deletions

View File

@ -184,6 +184,7 @@ INSTALLED_APPS = [
"taiga.searches",
"taiga.timeline",
"taiga.mdrender",
"taiga.export_import",
"south",
"reversion",

View File

View File

@ -0,0 +1,22 @@
from django.core.management.base import BaseCommand, CommandError
from optparse import make_option
from taiga.projects.models import Project
from taiga.export_import.renderers import ExportRenderer
from taiga.export_import.service import project_to_dict
class Command(BaseCommand):
args = '<project_slug project_slug ...>'
help = 'Export a project to json'
renderer_context = {"indent": 4}
renderer = ExportRenderer()
def handle(self, *args, **options):
for project_slug in args:
try:
project = Project.objects.get(slug=project_slug)
except Project.DoesNotExist:
raise CommandError('Project "%s" does not exist' % project_slug)
data = project_to_dict(project)
print(self.renderer.render(data, renderer_context=self.renderer_context).decode('utf-8'))

View File

@ -0,0 +1,18 @@
from django.core.management.base import BaseCommand, CommandError
from optparse import make_option
import json
from taiga.projects.models import Project
from taiga.export_import.renderers import ExportRenderer
from taiga.export_import.service import dict_to_project
class Command(BaseCommand):
args = '<dump_file> <owner-email>'
help = 'Export a project to json'
renderer_context = {"indent": 4}
renderer = ExportRenderer()
def handle(self, *args, **options):
data = json.loads(open(args[0], 'r').read())
dict_to_project(data, args[1])

View File

View File

@ -0,0 +1,4 @@
from rest_framework.renderers import UnicodeJSONRenderer
class ExportRenderer(UnicodeJSONRenderer):
pass

View File

@ -0,0 +1,315 @@
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
# Copyright (C) 2014 Jesús Espino <jespinog@gmail.com>
# Copyright (C) 2014 David Barragán <bameda@dbarragan.com>
# 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 <http://www.gnu.org/licenses/>.
from django.contrib.contenttypes.models import ContentType
from django.core.files.base import ContentFile
from rest_framework import serializers
import json
import base64
import os
import io
from collections import OrderedDict
from taiga.projects import models as projects_models
from taiga.projects.userstories import models as userstories_models
from taiga.projects.tasks import models as tasks_models
from taiga.projects.issues import models as issues_models
from taiga.projects.milestones import models as milestones_models
from taiga.projects.wiki import models as wiki_models
from taiga.projects.votes import models as votes_models
from taiga.projects.notifications import models as notifications_models
from taiga.projects.history import models as history_models
from taiga.projects.attachments import models as attachments_models
from taiga.users import models as users_models
from taiga.projects.votes import services as votes_service
from taiga.projects.history import services as history_service
from taiga.base.serializers import JsonField, PgArrayField
class AttachedFileField(serializers.WritableField):
read_only = False
def to_native(self, obj):
if not obj:
return None
return OrderedDict([
("data", base64.b64encode(obj.read()).decode('utf-8')),
("name", os.path.basename(obj.name)),
])
def from_native(self, data):
if not data:
return None
return ContentFile(base64.b64decode(data['data']), name=data['name'])
class UserRelatedField(serializers.RelatedField):
read_only = False
def to_native(self, obj):
if obj:
return obj.email
return None
def from_native(self, data):
try:
return users_models.User.objects.get(email=data)
except users_models.User.DoesNotExist:
return None
class ProjectRelatedField(serializers.RelatedField):
read_only = False
def __init__(self, slug_field, *args, **kwargs):
self.slug_field = slug_field
super().__init__(*args, **kwargs)
def to_native(self, obj):
if obj:
return getattr(obj, self.slug_field)
return None
def from_native(self, data):
try:
kwargs = {self.slug_field: data, "project": self.context['project']}
return self.queryset.get(**kwargs)
except self.parent.opts.model.DoesNotExist:
return None
class PointsExportSerializer(serializers.ModelSerializer):
class Meta:
model = projects_models.Points
exclude = ('id', 'project')
class UserStoryStatusExportSerializer(serializers.ModelSerializer):
class Meta:
model = projects_models.UserStoryStatus
exclude = ('id', 'project')
class TaskStatusExportSerializer(serializers.ModelSerializer):
class Meta:
model = projects_models.TaskStatus
exclude = ('id', 'project')
class IssueStatusExportSerializer(serializers.ModelSerializer):
class Meta:
model = projects_models.IssueStatus
exclude = ('id', 'project')
class PriorityExportSerializer(serializers.ModelSerializer):
class Meta:
model = projects_models.Priority
exclude = ('id', 'project')
class SeverityExportSerializer(serializers.ModelSerializer):
class Meta:
model = projects_models.Severity
exclude = ('id', 'project')
class IssueTypeExportSerializer(serializers.ModelSerializer):
class Meta:
model = projects_models.IssueType
exclude = ('id', 'project')
class RoleExportSerializer(serializers.ModelSerializer):
permissions = PgArrayField(required=False)
class Meta:
model = users_models.Role
exclude = ('id', 'project')
class MembershipExportSerializer(serializers.ModelSerializer):
user = UserRelatedField(required=False)
role = ProjectRelatedField(slug_field="slug")
class Meta:
model = projects_models.Membership
exclude = ('id', 'project')
def full_clean(self, instance):
return instance
class RolePointsExportSerializer(serializers.ModelSerializer):
role = ProjectRelatedField(slug_field="slug")
points = ProjectRelatedField(slug_field="name")
class Meta:
model = userstories_models.RolePoints
exclude = ('id', 'user_story')
class MilestoneExportSerializer(serializers.ModelSerializer):
owner = UserRelatedField(required=False)
watchers = UserRelatedField(many=True, required=False)
tasks_without_us = serializers.SerializerMethodField("get_tasks_without_us")
class Meta:
model = milestones_models.Milestone
exclude = ('id', 'project')
def get_tasks_without_us(self, obj):
queryset = tasks_models.Task.objects.filter(milestone=obj, user_story__isnull=True)
return TaskExportSerializer(queryset.order_by('ref'), many=True).data
class AttachmentExportSerializer(serializers.ModelSerializer):
owner = UserRelatedField()
attached_file = AttachedFileField()
class Meta:
model = attachments_models.Attachment
exclude = ('id', 'content_type', 'object_id', 'project')
class AttachmentExportSerializerMixin(serializers.ModelSerializer):
attachments = serializers.SerializerMethodField("get_attachments")
def get_attachments(self, obj):
content_type = ContentType.objects.get_for_model(obj.__class__)
attachments_qs = attachments_models.Attachment.objects.filter(object_id=obj.pk, content_type=content_type)
return AttachmentExportSerializer(attachments_qs, many=True).data
class TaskExportSerializer(AttachmentExportSerializerMixin, serializers.ModelSerializer):
owner = UserRelatedField(required=False)
status = ProjectRelatedField(slug_field="name", required=False)
milestone = ProjectRelatedField(slug_field="slug", required=False)
assigned_to = UserRelatedField(required=False)
watchers = UserRelatedField(many=True, required=False)
class Meta:
model = tasks_models.Task
exclude = ('id', 'project', 'user_story')
class UserStoryExportSerializer(AttachmentExportSerializerMixin, serializers.ModelSerializer):
role_points = RolePointsExportSerializer(many=True, required=False)
generated_from_issue = ProjectRelatedField(slug_field="ref", required=False)
owner = UserRelatedField(required=False)
status = ProjectRelatedField(slug_field="name", required=False)
tasks = TaskExportSerializer(many=True, required=False)
milestone = ProjectRelatedField(slug_field="slug", required=False)
watchers = UserRelatedField(many=True, required=False)
class Meta:
model = userstories_models.UserStory
exclude = ('id', 'project', 'points')
def _convert_user(user_pk):
try:
user = users_models.User.objects.get(pk=user_pk)
except users_models.User.DoesNotExist:
return "#imported#{}".format(user_pk)
return user.email
def _convert_user_tuple(user_tuple):
return (_convert_user(user_tuple[0]), user_tuple[1])
class HistoryExportSerializer(serializers.ModelSerializer):
user = serializers.SerializerMethodField("get_user")
diff = serializers.SerializerMethodField("get_diff")
snapshot = JsonField()
values = serializers.SerializerMethodField("get_values")
def get_user(self, obj):
return (_convert_user(obj.user['pk']), obj.user['name'])
def get_values(self, obj):
for key, value in obj.values.items():
if key == "users":
obj.values["users"] = dict(map(_convert_user_tuple, value.items()))
return obj.values
def get_diff(self, obj):
for key, value in obj.diff.items():
if key == "assigned_to":
obj.diff["assigned_to"] = map(_convert_user, value)
return obj.diff
class Meta:
model = history_models.HistoryEntry
class HistoryExportSerializerMixin(serializers.ModelSerializer):
history = serializers.SerializerMethodField("get_history")
def get_history(self, obj):
history_qs = history_service.get_history_queryset_by_model_instance(obj)
return HistoryExportSerializer(history_qs, many=True).data
class IssueExportSerializer(HistoryExportSerializerMixin, AttachmentExportSerializerMixin, serializers.ModelSerializer):
owner = UserRelatedField(required=False)
status = ProjectRelatedField(slug_field="name", required=False)
assigned_to = UserRelatedField(required=False)
priority = ProjectRelatedField(slug_field="name", required=False)
severity = ProjectRelatedField(slug_field="name", required=False)
type = ProjectRelatedField(slug_field="name", required=False)
milestone = ProjectRelatedField(slug_field="slug", required=False)
watchers = UserRelatedField(many=True, required=False)
votes = serializers.SerializerMethodField("get_votes")
def get_votes(self, obj):
return [x.email for x in votes_service.get_voters(obj)]
class Meta:
model = issues_models.Issue
exclude = ('id', 'project')
class WikiPageExportSerializer(AttachmentExportSerializerMixin, serializers.ModelSerializer):
owner = UserRelatedField(required=False)
last_modifier = UserRelatedField(required=False)
watchers = UserRelatedField(many=True, required=False)
class Meta:
model = wiki_models.WikiPage
exclude = ('id', 'project')
class WikiLinkExportSerializer(serializers.ModelSerializer):
class Meta:
model = wiki_models.WikiLink
exclude = ('id', 'project')
class ProjectExportSerializer(serializers.ModelSerializer):
owner = UserRelatedField()
default_points = serializers.SlugRelatedField(slug_field="name", required=False)
default_us_status = serializers.SlugRelatedField(slug_field="name", required=False)
default_task_status = serializers.SlugRelatedField(slug_field="name", required=False)
default_priority = serializers.SlugRelatedField(slug_field="name", required=False)
default_severity = serializers.SlugRelatedField(slug_field="name", required=False)
default_issue_status = serializers.SlugRelatedField(slug_field="name", required=False)
default_issue_type = serializers.SlugRelatedField(slug_field="name", required=False)
memberships = MembershipExportSerializer(many=True, required=False)
points = PointsExportSerializer(many=True, required=False)
us_statuses = UserStoryStatusExportSerializer(many=True, required=False)
task_statuses = TaskStatusExportSerializer(many=True, required=False)
issue_statuses = IssueStatusExportSerializer(many=True, required=False)
priorities = PriorityExportSerializer(many=True, required=False)
severities = SeverityExportSerializer(many=True, required=False)
issue_types = IssueTypeExportSerializer(many=True, required=False)
roles = RoleExportSerializer(many=True, required=False)
milestones = MilestoneExportSerializer(many=True, required=False)
wiki_pages = WikiPageExportSerializer(many=True, required=False)
wiki_links = WikiLinkExportSerializer(many=True, required=False)
user_stories = UserStoryExportSerializer(many=True, required=False)
issues = IssueExportSerializer(many=True, required=False)
tags_colors = JsonField(required=False)
anon_permissions = PgArrayField(required=False)
public_permissions = PgArrayField(required=False)
class Meta:
model = projects_models.Project
exclude = ('id', 'creation_template', 'members')

View File

@ -0,0 +1,196 @@
from . import serializers
from taiga.projects.models import Project
from django.db.models import signals
from django.db import transaction
from django.contrib.contenttypes.models import ContentType
def project_to_dict(project):
return serializers.ProjectExportSerializer(project).data
def dict_to_project(data, owner=None):
signals.pre_save.receivers = []
signals.post_save.receivers = []
signals.pre_delete.receivers = []
signals.post_delete.receivers = []
@transaction.atomic
def store_project(data):
project_data = {}
for key, value in data.items():
excluded_fields = [
"default_points", "default_us_status", "default_task_status",
"default_priority", "default_severity", "default_issue_status",
"default_issue_type", "memberships", "points", "us_statuses",
"task_statuses", "issue_statuses", "priorities", "severities",
"issue_types", "roles", "milestones", "wiki_pages",
"wiki_links", "notify_policies", "user_stories", "issues"
]
if key not in excluded_fields:
project_data[key] = value
serialized = serializers.ProjectExportSerializer(data=project_data)
serialized.is_valid()
serialized.object._importing = True
serialized.object.save()
return serialized.object
@transaction.atomic
def store_choices(project, data, field, relation, serializer, default_field):
relation.all().delete()
for point in data[field]:
serialized = serializer(data=point)
serialized.is_valid()
serialized.object.project = project
serialized.object._importing = True
serialized.save()
@transaction.atomic
def store_default_choices(project, data):
project.default_points = project.points.all().get(name=data['default_points'])
project.default_issue_type = project.issue_types.get(name=data['default_issue_type'])
project.default_issue_status = project.issue_statuses.get(name=data['default_issue_status'])
project.default_us_status = project.us_statuses.get(name=data['default_us_status'])
project.default_task_status = project.task_statuses.get(name=data['default_task_status'])
project.default_priority = project.priorities.get(name=data['default_priority'])
project.default_severity = project.severities.get(name=data['default_severity'])
project._importing = True
project.save()
@transaction.atomic
def store_roles(project, data):
project.roles.all().delete()
for role in data['roles']:
serialized = serializers.RoleExportSerializer(data=role)
serialized.is_valid()
serialized.object.project = project
serialized.object._importing = True
serialized.save()
@transaction.atomic
def store_memberships(project, data):
for membership in data['memberships']:
serialized = serializers.MembershipExportSerializer(data=membership, context={"project": project})
serialized.is_valid()
serialized.object.project = project
serialized.object._importing = True
serialized.save()
@transaction.atomic
def store_task(project, us, task):
serialized = serializers.TaskExportSerializer(data=task, context={"project": project})
serialized.is_valid()
serialized.object.user_story = us
serialized.object.project = project
serialized.object._importing = True
serialized.save()
for task_attachment in task['attachments']:
store_attachment(project, serialized.object, task_attachment)
@transaction.atomic
def store_milestones(project, data):
for milestone in data['milestones']:
serialized = serializers.MilestoneExportSerializer(data=milestone)
serialized.is_valid()
serialized.object.project = project
serialized.object._importing = True
serialized.save()
for task_without_us in milestone['tasks_without_us']:
store_task(project, None, task_without_us)
def store_attachment(project, obj, attachment):
serialized = serializers.AttachmentExportSerializer(data=attachment)
serialized.is_valid()
serialized.object.content_type = ContentType.objects.get_for_model(obj.__class__)
serialized.object.object_id = obj.id
serialized.object.project = project
serialized.object._importing = True
serialized.save()
@transaction.atomic
def store_wiki_pages(project, data):
for wiki_page in data['wiki_pages']:
serialized = serializers.WikiPageExportSerializer(data=wiki_page)
serialized.is_valid()
serialized.object.project = project
serialized.object._importing = True
serialized.save()
for attachment in wiki_page['attachments']:
store_attachment(project, serialized.object, attachment)
@transaction.atomic
def store_wiki_links(project, data):
for wiki_link in data['wiki_links']:
serialized = serializers.WikiLinkExportSerializer(data=wiki_link)
serialized.is_valid()
serialized.object.project = project
serialized.object._importing = True
serialized.save()
@transaction.atomic
def store_role_point(project, us, role_point):
serialized = serializers.RolePointsExportSerializer(data=role_point, context={"project": project} )
serialized.is_valid()
serialized.object.user_story = us
serialized.save()
@transaction.atomic
def store_user_stories(project, data):
for userstory in data['user_stories']:
userstory_data = {}
for key, value in userstory.items():
excluded_fields = [
'tasks', 'role_points'
]
if key not in excluded_fields:
userstory_data[key] = value
serialized_us = serializers.UserStoryExportSerializer(data=userstory_data, context={"project": project})
serialized_us.is_valid()
serialized_us.object.project = project
serialized_us.object._importing = True
serialized_us.save()
for task in userstory['tasks']:
store_task(project, serialized_us.object, task)
for us_attachment in userstory['attachments']:
store_attachment(project, serialized_us.object, us_attachment)
for role_point in userstory['role_points']:
store_role_point(project, serialized_us.object, role_point)
@transaction.atomic
def store_issues(project, data):
for issue in data['issues']:
serialized = serializers.IssueExportSerializer(data=issue, context={"project": project})
serialized.is_valid()
serialized.object.project = project
serialized.object._importing = True
serialized.save()
for attachment in issue['attachments']:
store_attachment(project, serialized.object, attachment)
if owner:
data['owner'] = owner
project = store_project(data)
store_choices(project, data, "points", project.points, serializers.PointsExportSerializer, "default_points")
store_choices(project, data, "issue_types", project.issue_types, serializers.IssueTypeExportSerializer, "default_issue_type")
store_choices(project, data, "issue_statuses", project.issue_statuses, serializers.IssueStatusExportSerializer, "default_issue_status")
store_choices(project, data, "us_statuses", project.us_statuses, serializers.UserStoryStatusExportSerializer, "default_us_status")
store_choices(project, data, "task_statuses", project.task_statuses, serializers.TaskStatusExportSerializer, "default_task_status")
store_choices(project, data, "priorities", project.priorities, serializers.PriorityExportSerializer, "default_priority")
store_choices(project, data, "severities", project.severities, serializers.SeverityExportSerializer, "default_severity")
store_default_choices(project, data)
store_roles(project, data)
store_memberships(project, data)
store_milestones(project, data)
store_wiki_pages(project, data)
store_wiki_links(project, data)
store_user_stories(project, data)
store_issues(project, data)

View File

@ -0,0 +1,211 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Attachment.modified_date'
db.alter_column('attachments_attachment', 'modified_date', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'Attachment.created_date'
db.alter_column('attachments_attachment', 'created_date', self.gf('django.db.models.fields.DateTimeField')())
def backwards(self, orm):
# Changing field 'Attachment.modified_date'
db.alter_column('attachments_attachment', 'modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True))
# Changing field 'Attachment.created_date'
db.alter_column('attachments_attachment', 'created_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
models = {
'attachments.attachment': {
'Meta': {'ordering': "['project', 'created_date']", 'object_name': 'Attachment'},
'attached_file': ('django.db.models.fields.files.FileField', [], {'max_length': '500', 'blank': 'True', 'null': 'True'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_deprecated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.User']", 'related_name': "'change_attachments'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'attachments'"})
},
'contenttypes.contenttype': {
'Meta': {'db_table': "'django_content_type'", 'unique_together': "(('app_label', 'model'),)", 'ordering': "('name',)", 'object_name': 'ContentType'},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'projects.issuestatus': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'IssueStatus'},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issue_statuses'"})
},
'projects.issuetype': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'IssueType'},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issue_types'"})
},
'projects.membership': {
'Meta': {'unique_together': "(('user', 'project'),)", 'ordering': "['project', 'user__full_name', 'user__username', 'user__email', 'email']", 'object_name': 'Membership'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'default': 'None', 'max_length': '255', 'blank': 'True', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invited_by_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'memberships'"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.Role']", 'related_name': "'memberships'"}),
'token': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '60', 'blank': 'True', 'null': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'null': 'True', 'blank': 'True', 'related_name': "'memberships'", 'to': "orm['users.User']"})
},
'projects.points': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Points'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'points'"}),
'value': ('django.db.models.fields.FloatField', [], {'default': 'None', 'null': 'True', 'blank': 'True'})
},
'projects.priority': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Priority'},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'priorities'"})
},
'projects.project': {
'Meta': {'ordering': "['name']", 'object_name': 'Project'},
'anon_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'default': '[]', 'null': 'True', 'blank': 'True'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'null': 'True', 'blank': 'True', 'related_name': "'projects'", 'to': "orm['projects.ProjectTemplate']"}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.IssueStatus']", 'related_name': "'+'"}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.IssueType']", 'related_name': "'+'"}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.Points']", 'related_name': "'+'"}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.Priority']", 'related_name': "'+'"}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.Severity']", 'related_name': "'+'"}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.TaskStatus']", 'related_name': "'+'"}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.UserStoryStatus']", 'related_name': "'+'"}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['users.User']", 'related_name': "'projects'", 'through': "orm['projects.Membership']"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250', 'unique': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.User']", 'related_name': "'owned_projects'"}),
'public_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'default': '[]', 'null': 'True', 'blank': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '250', 'blank': 'True', 'unique': 'True'}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'default': 'None', 'null': 'True', 'blank': 'True'}),
'tags_colors': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'default': '[]', 'dimension': '2', 'blank': 'True'}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'default': '0', 'null': 'True', 'blank': 'True'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True', 'null': 'True'})
},
'projects.projecttemplate': {
'Meta': {'ordering': "['name']", 'object_name': 'ProjectTemplate'},
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '250', 'blank': 'True', 'unique': 'True'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'max_length': '250', 'blank': 'True', 'null': 'True'})
},
'projects.severity': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Severity'},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'severities'"})
},
'projects.taskstatus': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'TaskStatus'},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'task_statuses'"})
},
'projects.userstorystatus': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'UserStoryStatus'},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'us_statuses'"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'null': 'True', 'blank': 'True'})
},
'users.role': {
'Meta': {'unique_together': "(('slug', 'project'),)", 'ordering': "['order', 'slug']", 'object_name': 'Role'},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'default': '[]', 'null': 'True', 'blank': 'True'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'roles'"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '250', 'blank': 'True'})
},
'users.user': {
'Meta': {'ordering': "['username']", 'object_name': 'User'},
'bio': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'color': ('django.db.models.fields.CharField', [], {'default': "'#b3bbb6'", 'max_length': '9', 'blank': 'True'}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20', 'blank': 'True'}),
'default_timezone': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20', 'blank': 'True'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_token': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'blank': 'True', 'null': 'True'}),
'full_name': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'github_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'new_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True', 'null': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'max_length': '500', 'blank': 'True', 'null': 'True'}),
'token': ('django.db.models.fields.CharField', [], {'default': 'None', 'max_length': '200', 'blank': 'True', 'null': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'})
}
}
complete_apps = ['attachments']

View File

@ -46,9 +46,10 @@ class Attachment(models.Model):
object_id = models.PositiveIntegerField(null=False, blank=False,
verbose_name=_("object id"))
content_object = generic.GenericForeignKey("content_type", "object_id")
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
created_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("created date"),
default=timezone.now)
modified_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("modified date"))
attached_file = models.FileField(max_length=500, null=True, blank=True,
@ -57,6 +58,7 @@ class Attachment(models.Model):
is_deprecated = models.BooleanField(default=False, verbose_name=_("is deprecated"))
description = models.TextField(null=False, blank=True, verbose_name=_("description"))
order = models.IntegerField(default=0, null=False, blank=False, verbose_name=_("order"))
_importing = None
class Meta:
verbose_name = "attachment"
@ -66,5 +68,11 @@ class Attachment(models.Model):
("view_attachment", "Can view attachment"),
)
def save(self, *args, **kwargs):
if not self._importing:
self.modified_date = timezone.now()
return super().save(*args, **kwargs)
def __str__(self):
return "Attachment: {}".format(self.id)

View File

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'HistoryEntry.created_at'
db.alter_column('history_historyentry', 'created_at', self.gf('django.db.models.fields.DateTimeField')())
def backwards(self, orm):
# Changing field 'HistoryEntry.created_at'
db.alter_column('history_historyentry', 'created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
models = {
'history.historyentry': {
'Meta': {'ordering': "['created_at']", 'object_name': 'HistoryEntry'},
'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'comment_html': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'diff': ('django_pgjson.fields.JsonField', [], {'default': 'None', 'blank': 'False'}),
'id': ('django.db.models.fields.CharField', [], {'primary_key': 'True', 'default': "'9571feee-2ebf-11e4-8a54-1c75086d5bff'", 'unique': 'True', 'max_length': '255'}),
'is_snapshot': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'default': 'None', 'null': 'True', 'blank': 'True'}),
'snapshot': ('django_pgjson.fields.JsonField', [], {'default': 'None', 'blank': 'False'}),
'type': ('django.db.models.fields.SmallIntegerField', [], {}),
'user': ('django_pgjson.fields.JsonField', [], {'default': 'None'}),
'values': ('django_pgjson.fields.JsonField', [], {'default': 'None', 'blank': 'False'})
}
}
complete_apps = ['history']

View File

@ -15,6 +15,7 @@
import uuid
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.db import models
from django.db.models.loading import get_model
from django.utils.functional import cached_property
@ -36,7 +37,7 @@ class HistoryEntry(models.Model):
editable=False, default=lambda: str(uuid.uuid1()))
user = JsonField(blank=True, default=None, null=True)
created_at = models.DateTimeField(auto_now_add=True)
created_at = models.DateTimeField(default=timezone.now)
type = models.SmallIntegerField(choices=HISTORY_TYPE_CHOICES)
is_snapshot = models.BooleanField(default=False)

View File

@ -0,0 +1,235 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Issue.modified_date'
db.alter_column('issues_issue', 'modified_date', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'Issue.subject'
db.alter_column('issues_issue', 'subject', self.gf('django.db.models.fields.TextField')())
# Changing field 'Issue.created_date'
db.alter_column('issues_issue', 'created_date', self.gf('django.db.models.fields.DateTimeField')())
def backwards(self, orm):
# Changing field 'Issue.modified_date'
db.alter_column('issues_issue', 'modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True))
# Changing field 'Issue.subject'
db.alter_column('issues_issue', 'subject', self.gf('django.db.models.fields.CharField')(max_length=500))
# Changing field 'Issue.created_date'
db.alter_column('issues_issue', 'created_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
models = {
'issues.issue': {
'Meta': {'object_name': 'Issue', 'ordering': "['project', '-created_date']"},
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'related_name': "'issues_assigned_to_me'", 'null': 'True', 'default': 'None'}),
'blocked_note': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'finished_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['milestones.Milestone']", 'related_name': "'issues'", 'null': 'True', 'default': 'None'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'related_name': "'owned_issues'", 'null': 'True', 'default': 'None'}),
'priority': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.Priority']"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.Project']"}),
'ref': ('django.db.models.fields.BigIntegerField', [], {'blank': 'True', 'null': 'True', 'db_index': 'True', 'default': 'None'}),
'severity': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.Severity']"}),
'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.IssueStatus']"}),
'subject': ('django.db.models.fields.TextField', [], {}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'null': 'True', 'default': 'None'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.IssueType']"}),
'version': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'to': "orm['users.User']", 'related_name': "'issues_issue+'", 'null': 'True', 'symmetrical': 'False'})
},
'milestones.milestone': {
'Meta': {'object_name': 'Milestone', 'unique_together': "[('name', 'project'), ('slug', 'project')]", 'ordering': "['project', 'created_date']"},
'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'disponibility': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'null': 'True', 'default': '0.0'}),
'estimated_finish': ('django.db.models.fields.DateField', [], {}),
'estimated_start': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'db_index': 'True'}),
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'related_name': "'owned_milestones'", 'null': 'True'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'milestones'", 'to': "orm['projects.Project']"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'to': "orm['users.User']", 'related_name': "'milestones_milestone+'", 'null': 'True', 'symmetrical': 'False'})
},
'projects.issuestatus': {
'Meta': {'object_name': 'IssueStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_statuses'", 'to': "orm['projects.Project']"})
},
'projects.issuetype': {
'Meta': {'object_name': 'IssueType', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_types'", 'to': "orm['projects.Project']"})
},
'projects.membership': {
'Meta': {'object_name': 'Membership', 'unique_together': "(('user', 'project'),)", 'ordering': "['project', 'user__full_name', 'user__username', 'user__email', 'email']"},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '255', 'null': 'True', 'default': 'None'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invited_by_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['projects.Project']"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['users.Role']"}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '60', 'null': 'True', 'default': 'None'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'related_name': "'memberships'", 'null': 'True', 'default': 'None'})
},
'projects.points': {
'Meta': {'object_name': 'Points', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'points'", 'to': "orm['projects.Project']"}),
'value': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'null': 'True', 'default': 'None'})
},
'projects.priority': {
'Meta': {'object_name': 'Priority', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'priorities'", 'to': "orm['projects.Project']"})
},
'projects.project': {
'Meta': {'object_name': 'Project', 'ordering': "['name']"},
'anon_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'null': 'True', 'default': '[]'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['projects.ProjectTemplate']", 'related_name': "'projects'", 'null': 'True', 'default': 'None'}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.IssueStatus']", 'unique': 'True', 'blank': 'True', 'related_name': "'+'"}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.IssueType']", 'unique': 'True', 'blank': 'True', 'related_name': "'+'"}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.Points']", 'unique': 'True', 'blank': 'True', 'related_name': "'+'"}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.Priority']", 'unique': 'True', 'blank': 'True', 'related_name': "'+'"}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.Severity']", 'unique': 'True', 'blank': 'True', 'related_name': "'+'"}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.TaskStatus']", 'unique': 'True', 'blank': 'True', 'related_name': "'+'"}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['projects.UserStoryStatus']", 'unique': 'True', 'blank': 'True', 'related_name': "'+'"}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'through': "orm['projects.Membership']", 'related_name': "'projects'", 'to': "orm['users.User']", 'symmetrical': 'False'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250', 'unique': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_projects'", 'to': "orm['users.User']"}),
'public_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'null': 'True', 'default': '[]'}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250', 'unique': 'True'}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'null': 'True', 'default': 'None'}),
'tags_colors': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dimension': '2', 'dbtype': "'text'", 'default': '[]'}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True', 'default': '0'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'})
},
'projects.projecttemplate': {
'Meta': {'object_name': 'ProjectTemplate', 'ordering': "['name']"},
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250', 'unique': 'True'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'})
},
'projects.severity': {
'Meta': {'object_name': 'Severity', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'severities'", 'to': "orm['projects.Project']"})
},
'projects.taskstatus': {
'Meta': {'object_name': 'TaskStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_statuses'", 'to': "orm['projects.Project']"})
},
'projects.userstorystatus': {
'Meta': {'object_name': 'UserStoryStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'us_statuses'", 'to': "orm['projects.Project']"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True', 'default': 'None'})
},
'users.role': {
'Meta': {'object_name': 'Role', 'unique_together': "(('slug', 'project'),)", 'ordering': "['order', 'slug']"},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'null': 'True', 'default': '[]'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'roles'", 'to': "orm['projects.Project']"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'})
},
'users.user': {
'Meta': {'object_name': 'User', 'ordering': "['username']"},
'bio': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
'color': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '9', 'default': "'#a294a6'"}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '20', 'default': "''"}),
'default_timezone': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '20', 'default': "''"}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75'}),
'email_token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '200', 'null': 'True', 'default': 'None'}),
'full_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '256'}),
'github_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'new_email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75', 'null': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'max_length': '500', 'null': 'True'}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '200', 'null': 'True', 'default': 'None'}),
'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'})
}
}
complete_apps = ['issues']

View File

@ -47,9 +47,10 @@ class Issue(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, models.
verbose_name=_("milestone"))
project = models.ForeignKey("projects.Project", null=False, blank=False,
related_name="issues", verbose_name=_("project"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
created_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("created date"),
default=timezone.now)
modified_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("modified date"))
finished_date = models.DateTimeField(null=True, blank=True,
verbose_name=_("finished date"))
@ -60,6 +61,7 @@ class Issue(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, models.
default=None, related_name="issues_assigned_to_me",
verbose_name=_("assigned to"))
attachments = generic.GenericRelation("attachments.Attachment")
_importing = None
class Meta:
verbose_name = "issue"
@ -70,6 +72,12 @@ class Issue(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, models.
("view_issue", "Can view issue"),
)
def save(self, *args, **kwargs):
if not self._importing:
self.modified_date = timezone.now()
return super().save(*args, **kwargs)
def __str__(self):
return "({1}) {0}".format(self.ref, self.subject)

View File

@ -34,6 +34,7 @@ class IssueSerializer(serializers.ModelSerializer):
class Meta:
model = models.Issue
read_only_fields = ('id', 'ref', 'created_date', 'modified_date')
def get_comment(self, obj):
# NOTE: This method and field is necessary to historical comments work

View File

@ -0,0 +1,208 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Membership.created_at'
db.alter_column('projects_membership', 'created_at', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'Project.created_date'
db.alter_column('projects_project', 'created_date', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'Project.modified_date'
db.alter_column('projects_project', 'modified_date', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'ProjectTemplate.created_date'
db.alter_column('projects_projecttemplate', 'created_date', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'ProjectTemplate.modified_date'
db.alter_column('projects_projecttemplate', 'modified_date', self.gf('django.db.models.fields.DateTimeField')())
def backwards(self, orm):
# Changing field 'Membership.created_at'
db.alter_column('projects_membership', 'created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
# Changing field 'Project.created_date'
db.alter_column('projects_project', 'created_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
# Changing field 'Project.modified_date'
db.alter_column('projects_project', 'modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True))
# Changing field 'ProjectTemplate.created_date'
db.alter_column('projects_projecttemplate', 'created_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
# Changing field 'ProjectTemplate.modified_date'
db.alter_column('projects_projecttemplate', 'modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True))
models = {
'projects.issuestatus': {
'Meta': {'ordering': "['project', 'order', 'name']", 'object_name': 'IssueStatus', 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_statuses'", 'to': "orm['projects.Project']"})
},
'projects.issuetype': {
'Meta': {'ordering': "['project', 'order', 'name']", 'object_name': 'IssueType', 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_types'", 'to': "orm['projects.Project']"})
},
'projects.membership': {
'Meta': {'ordering': "['project', 'user__full_name', 'user__username', 'user__email', 'email']", 'object_name': 'Membership', 'unique_together': "(('user', 'project'),)"},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'null': 'True', 'blank': 'True', 'max_length': '255', 'default': 'None'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invited_by_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['projects.Project']"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['users.Role']"}),
'token': ('django.db.models.fields.CharField', [], {'null': 'True', 'blank': 'True', 'max_length': '60', 'default': 'None'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'blank': 'True', 'to': "orm['users.User']", 'related_name': "'memberships'", 'default': 'None'})
},
'projects.points': {
'Meta': {'ordering': "['project', 'order', 'name']", 'object_name': 'Points', 'unique_together': "(('project', 'name'),)"},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'points'", 'to': "orm['projects.Project']"}),
'value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'blank': 'True', 'default': 'None'})
},
'projects.priority': {
'Meta': {'ordering': "['project', 'order', 'name']", 'object_name': 'Priority', 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'priorities'", 'to': "orm['projects.Project']"})
},
'projects.project': {
'Meta': {'ordering': "['name']", 'object_name': 'Project'},
'anon_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'blank': 'True', 'default': '[]', 'null': 'True'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'blank': 'True', 'to': "orm['projects.ProjectTemplate']", 'related_name': "'projects'", 'default': 'None'}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.IssueStatus']", 'related_name': "'+'"}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.IssueType']", 'related_name': "'+'"}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.Points']", 'related_name': "'+'"}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.Priority']", 'related_name': "'+'"}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.Severity']", 'related_name': "'+'"}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.TaskStatus']", 'related_name': "'+'"}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL', 'blank': 'True', 'to': "orm['projects.UserStoryStatus']", 'related_name': "'+'"}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'through': "orm['projects.Membership']", 'related_name': "'projects'", 'to': "orm['users.User']", 'symmetrical': 'False'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250', 'unique': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_projects'", 'to': "orm['users.User']"}),
'public_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'blank': 'True', 'default': '[]', 'null': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250', 'unique': 'True'}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'blank': 'True', 'default': 'None', 'null': 'True'}),
'tags_colors': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'blank': 'True', 'dimension': '2', 'default': '[]'}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True', 'default': '0'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'null': 'True', 'blank': 'True', 'max_length': '250'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'null': 'True', 'blank': 'True', 'max_length': '250'})
},
'projects.projecttemplate': {
'Meta': {'ordering': "['name']", 'object_name': 'ProjectTemplate'},
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250', 'unique': 'True'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'null': 'True', 'blank': 'True', 'max_length': '250'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'null': 'True', 'blank': 'True', 'max_length': '250'})
},
'projects.severity': {
'Meta': {'ordering': "['project', 'order', 'name']", 'object_name': 'Severity', 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'severities'", 'to': "orm['projects.Project']"})
},
'projects.taskstatus': {
'Meta': {'ordering': "['project', 'order', 'name']", 'object_name': 'TaskStatus', 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_statuses'", 'to': "orm['projects.Project']"})
},
'projects.userstorystatus': {
'Meta': {'ordering': "['project', 'order', 'name']", 'object_name': 'UserStoryStatus', 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'us_statuses'", 'to': "orm['projects.Project']"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True', 'default': 'None'})
},
'users.role': {
'Meta': {'ordering': "['order', 'slug']", 'object_name': 'Role', 'unique_together': "(('slug', 'project'),)"},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('djorm_pgarray.fields.TextArrayField', [], {'dbtype': "'text'", 'blank': 'True', 'default': '[]', 'null': 'True'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'roles'", 'to': "orm['projects.Project']"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'})
},
'users.user': {
'Meta': {'ordering': "['username']", 'object_name': 'User'},
'bio': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
'color': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '9', 'default': "'#8e74aa'"}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '20', 'default': "''"}),
'default_timezone': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '20', 'default': "''"}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75'}),
'email_token': ('django.db.models.fields.CharField', [], {'null': 'True', 'blank': 'True', 'max_length': '200', 'default': 'None'}),
'full_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '256'}),
'github_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'new_email': ('django.db.models.fields.EmailField', [], {'null': 'True', 'blank': 'True', 'max_length': '75'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'null': 'True', 'blank': 'True', 'max_length': '500'}),
'token': ('django.db.models.fields.CharField', [], {'null': 'True', 'blank': 'True', 'max_length': '200', 'default': 'None'}),
'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'})
}
}
complete_apps = ['projects']

View File

@ -0,0 +1,218 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Removing unique constraint on 'Milestone', fields ['slug']
db.delete_unique('milestones_milestone', ['slug'])
# Changing field 'Milestone.created_date'
db.alter_column('milestones_milestone', 'created_date', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'Milestone.modified_date'
db.alter_column('milestones_milestone', 'modified_date', self.gf('django.db.models.fields.DateTimeField')())
# Adding unique constraint on 'Milestone', fields ['slug', 'project']
db.create_unique('milestones_milestone', ['slug', 'project_id'])
def backwards(self, orm):
# Removing unique constraint on 'Milestone', fields ['slug', 'project']
db.delete_unique('milestones_milestone', ['slug', 'project_id'])
# Adding unique constraint on 'Milestone', fields ['slug']
db.create_unique('milestones_milestone', ['slug'])
# Changing field 'Milestone.created_date'
db.alter_column('milestones_milestone', 'created_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
# Changing field 'Milestone.modified_date'
db.alter_column('milestones_milestone', 'modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True))
models = {
'milestones.milestone': {
'Meta': {'unique_together': "[('name', 'project'), ('slug', 'project')]", 'object_name': 'Milestone', 'ordering': "['project', 'created_date']"},
'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'disponibility': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'default': '0.0', 'null': 'True'}),
'estimated_finish': ('django.db.models.fields.DateField', [], {}),
'estimated_start': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'db_index': 'True'}),
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'null': 'True', 'related_name': "'owned_milestones'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'milestones'"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'to': "orm['users.User']", 'symmetrical': 'False', 'null': 'True', 'related_name': "'milestones_milestone+'"})
},
'projects.issuestatus': {
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'IssueStatus', 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issue_statuses'"})
},
'projects.issuetype': {
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'IssueType', 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issue_types'"})
},
'projects.membership': {
'Meta': {'unique_together': "(('user', 'project'),)", 'object_name': 'Membership', 'ordering': "['project', 'user__full_name', 'user__username', 'user__email', 'email']"},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '255', 'default': 'None', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invited_by_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'memberships'"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.Role']", 'related_name': "'memberships'"}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '60', 'default': 'None', 'null': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['users.User']", 'default': 'None', 'null': 'True', 'related_name': "'memberships'"})
},
'projects.points': {
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'Points', 'ordering': "['project', 'order', 'name']"},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'points'"}),
'value': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'default': 'None', 'null': 'True'})
},
'projects.priority': {
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'Priority', 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'priorities'"})
},
'projects.project': {
'Meta': {'object_name': 'Project', 'ordering': "['name']"},
'anon_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'default': '[]', 'null': 'True', 'dbtype': "'text'"}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'to': "orm['projects.ProjectTemplate']", 'default': 'None', 'null': 'True', 'related_name': "'projects'"}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'to': "orm['projects.IssueStatus']", 'unique': 'True', 'null': 'True'}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'to': "orm['projects.IssueType']", 'unique': 'True', 'null': 'True'}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'to': "orm['projects.Points']", 'unique': 'True', 'null': 'True'}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'to': "orm['projects.Priority']", 'unique': 'True', 'null': 'True'}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'to': "orm['projects.Severity']", 'unique': 'True', 'null': 'True'}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'to': "orm['projects.TaskStatus']", 'unique': 'True', 'null': 'True'}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'to': "orm['projects.UserStoryStatus']", 'unique': 'True', 'null': 'True'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['users.User']", 'through': "orm['projects.Membership']", 'symmetrical': 'False', 'related_name': "'projects'"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250', 'unique': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.User']", 'related_name': "'owned_projects'"}),
'public_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'default': '[]', 'null': 'True', 'dbtype': "'text'"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250', 'unique': 'True'}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'default': 'None', 'null': 'True', 'dbtype': "'text'"}),
'tags_colors': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'default': '[]', 'dbtype': "'text'", 'dimension': '2'}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'default': '0', 'null': 'True'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'})
},
'projects.projecttemplate': {
'Meta': {'object_name': 'ProjectTemplate', 'ordering': "['name']"},
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250', 'unique': 'True'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'})
},
'projects.severity': {
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'Severity', 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'severities'"})
},
'projects.taskstatus': {
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'TaskStatus', 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'task_statuses'"})
},
'projects.userstorystatus': {
'Meta': {'unique_together': "(('project', 'name'),)", 'object_name': 'UserStoryStatus', 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'max_length': '20', 'default': "'#999999'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'us_statuses'"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'default': 'None', 'null': 'True'})
},
'users.role': {
'Meta': {'unique_together': "(('slug', 'project'),)", 'object_name': 'Role', 'ordering': "['order', 'slug']"},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'default': '[]', 'null': 'True', 'dbtype': "'text'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'roles'"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'})
},
'users.user': {
'Meta': {'object_name': 'User', 'ordering': "['username']"},
'bio': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
'color': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '9', 'default': "'#3f564d'"}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '20', 'default': "''"}),
'default_timezone': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '20', 'default': "''"}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75'}),
'email_token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '200', 'default': 'None', 'null': 'True'}),
'full_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '256'}),
'github_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'new_email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75', 'null': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'max_length': '500', 'null': 'True'}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '200', 'default': 'None', 'null': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'})
}
}
complete_apps = ['milestones']

View File

@ -17,6 +17,7 @@
from django.db import models
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from taiga.base.utils.slug import slugify_uniquely
from taiga.base.utils.dicts import dict_sum
@ -31,7 +32,7 @@ class Milestone(WatchedModelMixin, models.Model):
name = models.CharField(max_length=200, db_index=True, null=False, blank=False,
verbose_name=_("name"))
# TODO: Change the unique restriction to a unique together with the project id
slug = models.SlugField(max_length=250, unique=True, null=False, blank=True,
slug = models.SlugField(max_length=250, db_index=True, null=False, blank=True,
verbose_name=_("slug"))
owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
related_name="owned_milestones", verbose_name=_("owner"))
@ -39,9 +40,10 @@ class Milestone(WatchedModelMixin, models.Model):
related_name="milestones", verbose_name=_("project"))
estimated_start = models.DateField(verbose_name=_("estimated start date"))
estimated_finish = models.DateField(verbose_name=_("estimated finish date"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
created_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("created date"),
default=timezone.now)
modified_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("modified date"))
closed = models.BooleanField(default=False, null=False, blank=True,
verbose_name=_("is closed"))
@ -49,12 +51,13 @@ class Milestone(WatchedModelMixin, models.Model):
verbose_name=_("disponibility"))
order = models.PositiveSmallIntegerField(default=1, null=False, blank=False,
verbose_name=_("order"))
_importing = None
class Meta:
verbose_name = "milestone"
verbose_name_plural = "milestones"
ordering = ["project", "created_date"]
unique_together = ("name", "project")
unique_together = [("name", "project"), ("slug", "project")]
permissions = (
("view_milestone", "Can view milestone"),
)
@ -66,6 +69,8 @@ class Milestone(WatchedModelMixin, models.Model):
return "<Milestone {0}>".format(self.id)
def save(self, *args, **kwargs):
if not self._importing:
self.modified_date = timezone.now()
if not self.slug:
self.slug = slugify_uniquely(self.name, self.__class__)

View File

@ -32,6 +32,7 @@ class MilestoneSerializer(serializers.ModelSerializer):
class Meta:
model = models.Milestone
read_only_fields = ('id', 'created_date', 'modified_date')
def get_total_points(self, obj):
return sum(obj.total_points.values())

View File

@ -62,7 +62,7 @@ class Membership(models.Model):
# Invitation metadata
email = models.EmailField(max_length=255, default=None, null=True, blank=True,
verbose_name=_("email"))
created_at = models.DateTimeField(auto_now_add=True, default=timezone.now,
created_at = models.DateTimeField(default=timezone.now,
verbose_name=_("creado el"))
token = models.CharField(max_length=60, blank=True, null=True, default=None,
verbose_name=_("token"))
@ -122,9 +122,10 @@ class Project(ProjectDefaults, TaggedMixin, models.Model):
verbose_name=_("slug"))
description = models.TextField(null=False, blank=False,
verbose_name=_("description"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
created_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("created date"),
default=timezone.now)
modified_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("modified date"))
owner = models.ForeignKey(settings.AUTH_USER_MODEL, null=False, blank=False,
related_name="owned_projects", verbose_name=_("owner"))
@ -164,6 +165,7 @@ class Project(ProjectDefaults, TaggedMixin, models.Model):
verbose_name=_("is private"))
tags_colors = TextArrayField(dimension=2, null=False, blank=True, verbose_name=_("tags colors"), default=[])
_importing = None
class Meta:
verbose_name = "project"
@ -180,6 +182,9 @@ class Project(ProjectDefaults, TaggedMixin, models.Model):
return "<Project {0}>".format(self.id)
def save(self, *args, **kwargs):
if not self._importing:
self.modified_date = timezone.now()
if not self.slug:
base_slug = slugify_uniquely(self.name, self.__class__)
slug = base_slug
@ -471,9 +476,10 @@ class ProjectTemplate(models.Model):
verbose_name=_("slug"), unique=True)
description = models.TextField(null=False, blank=False,
verbose_name=_("description"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
created_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("created date"),
default=timezone.now)
modified_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("modified date"))
default_owner_role = models.CharField(max_length=50, null=False,
blank=False,
@ -502,6 +508,7 @@ class ProjectTemplate(models.Model):
priorities = JsonField(null=True, blank=True, verbose_name=_("priorities"))
severities = JsonField(null=True, blank=True, verbose_name=_("severities"))
roles = JsonField(null=True, blank=True, verbose_name=_("roles"))
_importing = None
class Meta:
verbose_name = "project template"
@ -515,6 +522,8 @@ class ProjectTemplate(models.Model):
return "<Project Template {0}>".format(self.slug)
def save(self, *args, **kwargs):
if not self._importing:
self.modified_date = timezone.now()
super().save(*args, **kwargs)
def load_data_from_project(self, project):

View File

@ -0,0 +1,207 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'NotifyPolicy'
db.create_table('notifications_notifypolicy', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('project', self.gf('django.db.models.fields.related.ForeignKey')(related_name='notify_policies', to=orm['projects.Project'])),
('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='notify_policies', to=orm['users.User'])),
('notify_level', self.gf('django.db.models.fields.SmallIntegerField')()),
('created_at', self.gf('django.db.models.fields.DateTimeField')(default=datetime.datetime.now)),
('modified_at', self.gf('django.db.models.fields.DateTimeField')()),
))
db.send_create_signal('notifications', ['NotifyPolicy'])
# Adding unique constraint on 'NotifyPolicy', fields ['project', 'user']
db.create_unique('notifications_notifypolicy', ['project_id', 'user_id'])
def backwards(self, orm):
# Removing unique constraint on 'NotifyPolicy', fields ['project', 'user']
db.delete_unique('notifications_notifypolicy', ['project_id', 'user_id'])
# Deleting model 'NotifyPolicy'
db.delete_table('notifications_notifypolicy')
models = {
'notifications.notifypolicy': {
'Meta': {'object_name': 'NotifyPolicy', 'unique_together': "(('project', 'user'),)", 'ordering': "['created_at']"},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {}),
'notify_level': ('django.db.models.fields.SmallIntegerField', [], {}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'notify_policies'", 'to': "orm['projects.Project']"}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'notify_policies'", 'to': "orm['users.User']"})
},
'projects.issuestatus': {
'Meta': {'object_name': 'IssueStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_statuses'", 'to': "orm['projects.Project']"})
},
'projects.issuetype': {
'Meta': {'object_name': 'IssueType', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_types'", 'to': "orm['projects.Project']"})
},
'projects.membership': {
'Meta': {'object_name': 'Membership', 'unique_together': "(('user', 'project'),)", 'ordering': "['project', 'user__full_name', 'user__username', 'user__email', 'email']"},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'default': 'None', 'blank': 'True', 'null': 'True', 'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invited_by_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['projects.Project']"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['users.Role']"}),
'token': ('django.db.models.fields.CharField', [], {'default': 'None', 'blank': 'True', 'null': 'True', 'max_length': '60'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'blank': 'True', 'related_name': "'memberships'", 'null': 'True', 'to': "orm['users.User']"})
},
'projects.points': {
'Meta': {'object_name': 'Points', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'points'", 'to': "orm['projects.Project']"}),
'value': ('django.db.models.fields.FloatField', [], {'default': 'None', 'blank': 'True', 'null': 'True'})
},
'projects.priority': {
'Meta': {'object_name': 'Priority', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'priorities'", 'to': "orm['projects.Project']"})
},
'projects.project': {
'Meta': {'object_name': 'Project', 'ordering': "['name']"},
'anon_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'default': '[]', 'blank': 'True', 'null': 'True', 'dbtype': "'text'"}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'blank': 'True', 'related_name': "'projects'", 'null': 'True', 'to': "orm['projects.ProjectTemplate']"}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.IssueStatus']", 'null': 'True'}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.IssueType']", 'null': 'True'}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.Points']", 'null': 'True'}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.Priority']", 'null': 'True'}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.Severity']", 'null': 'True'}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.TaskStatus']", 'null': 'True'}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.UserStoryStatus']", 'null': 'True'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['users.User']", 'related_name': "'projects'", 'through': "orm['projects.Membership']"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '250'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_projects'", 'to': "orm['users.User']"}),
'public_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'default': '[]', 'blank': 'True', 'null': 'True', 'dbtype': "'text'"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'unique': 'True', 'max_length': '250'}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'default': 'None', 'blank': 'True', 'null': 'True', 'dbtype': "'text'"}),
'tags_colors': ('djorm_pgarray.fields.TextArrayField', [], {'default': '[]', 'blank': 'True', 'dimension': '2', 'dbtype': "'text'"}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True', 'null': 'True'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'})
},
'projects.projecttemplate': {
'Meta': {'object_name': 'ProjectTemplate', 'ordering': "['name']"},
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'unique': 'True', 'max_length': '250'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'})
},
'projects.severity': {
'Meta': {'object_name': 'Severity', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'severities'", 'to': "orm['projects.Project']"})
},
'projects.taskstatus': {
'Meta': {'object_name': 'TaskStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_statuses'", 'to': "orm['projects.Project']"})
},
'projects.userstorystatus': {
'Meta': {'object_name': 'UserStoryStatus', 'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'us_statuses'", 'to': "orm['projects.Project']"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'default': 'None', 'blank': 'True', 'null': 'True'})
},
'users.role': {
'Meta': {'object_name': 'Role', 'unique_together': "(('slug', 'project'),)", 'ordering': "['order', 'slug']"},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('djorm_pgarray.fields.TextArrayField', [], {'default': '[]', 'blank': 'True', 'null': 'True', 'dbtype': "'text'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'roles'", 'to': "orm['projects.Project']"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'})
},
'users.user': {
'Meta': {'object_name': 'User', 'ordering': "['username']"},
'bio': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'color': ('django.db.models.fields.CharField', [], {'default': "'#35acb0'", 'blank': 'True', 'max_length': '9'}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'default': "''", 'blank': 'True', 'max_length': '20'}),
'default_timezone': ('django.db.models.fields.CharField', [], {'default': "''", 'blank': 'True', 'max_length': '20'}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75'}),
'email_token': ('django.db.models.fields.CharField', [], {'default': 'None', 'blank': 'True', 'null': 'True', 'max_length': '200'}),
'full_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '256'}),
'github_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'new_email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'null': 'True', 'max_length': '75'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'null': 'True', 'max_length': '500'}),
'token': ('django.db.models.fields.CharField', [], {'default': 'None', 'blank': 'True', 'null': 'True', 'max_length': '200'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
}
}
complete_apps = ['notifications']

View File

@ -16,6 +16,7 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from .choices import NOTIFY_LEVEL_CHOICES
@ -25,13 +26,20 @@ class NotifyPolicy(models.Model):
This class represents a persistence for
project user notifications preference.
"""
project = models.ForeignKey("projects.Project", related_name="+")
user = models.ForeignKey("users.User", related_name="+")
project = models.ForeignKey("projects.Project", related_name="notify_policies")
user = models.ForeignKey("users.User", related_name="notify_policies")
notify_level = models.SmallIntegerField(choices=NOTIFY_LEVEL_CHOICES)
created_at = models.DateTimeField(auto_now_add=True)
modified_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(default=timezone.now)
modified_at = models.DateTimeField()
_importing = None
class Meta:
unique_together = ("project", "user",)
ordering = ["created_at"]
def save(self, *args, **kwargs):
if not self._importing:
self.modified_at = timezone.now()
return super().save(*args, **kwargs)

View File

@ -0,0 +1,200 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Reference.created_at'
db.alter_column('references_reference', 'created_at', self.gf('django.db.models.fields.DateTimeField')())
def backwards(self, orm):
# Changing field 'Reference.created_at'
db.alter_column('references_reference', 'created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
models = {
'contenttypes.contenttype': {
'Meta': {'object_name': 'ContentType', 'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'projects.issuestatus': {
'Meta': {'object_name': 'IssueStatus', 'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issue_statuses'"})
},
'projects.issuetype': {
'Meta': {'object_name': 'IssueType', 'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issue_types'"})
},
'projects.membership': {
'Meta': {'object_name': 'Membership', 'ordering': "['project', 'user__full_name', 'user__username', 'user__email', 'email']", 'unique_together': "(('user', 'project'),)"},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invited_by_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'memberships'"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.Role']", 'related_name': "'memberships'"}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'max_length': '60'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'related_name': "'memberships'", 'to': "orm['users.User']"})
},
'projects.points': {
'Meta': {'object_name': 'Points', 'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)"},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'points'"}),
'value': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'null': 'True', 'default': 'None'})
},
'projects.priority': {
'Meta': {'object_name': 'Priority', 'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'priorities'"})
},
'projects.project': {
'Meta': {'object_name': 'Project', 'ordering': "['name']"},
'anon_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'null': 'True', 'default': '[]', 'dbtype': "'text'"}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'related_name': "'projects'", 'to': "orm['projects.ProjectTemplate']"}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.IssueStatus']", 'related_name': "'+'"}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.IssueType']", 'related_name': "'+'"}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.Points']", 'related_name': "'+'"}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.Priority']", 'related_name': "'+'"}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.Severity']", 'related_name': "'+'"}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.TaskStatus']", 'related_name': "'+'"}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'null': 'True', 'on_delete': 'models.SET_NULL', 'unique': 'True', 'to': "orm['projects.UserStoryStatus']", 'related_name': "'+'"}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['users.User']", 'symmetrical': 'False', 'related_name': "'projects'", 'through': "orm['projects.Membership']"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250', 'unique': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.User']", 'related_name': "'owned_projects'"}),
'public_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'null': 'True', 'default': '[]', 'dbtype': "'text'"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250', 'unique': 'True'}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'dbtype': "'text'"}),
'tags_colors': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'default': '[]', 'dbtype': "'text'", 'dimension': '2'}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True', 'default': '0'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'})
},
'projects.projecttemplate': {
'Meta': {'object_name': 'ProjectTemplate', 'ordering': "['name']"},
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250', 'unique': 'True'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'max_length': '250'})
},
'projects.severity': {
'Meta': {'object_name': 'Severity', 'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'severities'"})
},
'projects.taskstatus': {
'Meta': {'object_name': 'TaskStatus', 'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'task_statuses'"})
},
'projects.userstorystatus': {
'Meta': {'object_name': 'UserStoryStatus', 'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)"},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'us_statuses'"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True', 'default': 'None'})
},
'references.reference': {
'Meta': {'object_name': 'Reference', 'ordering': "['created_at']", 'unique_together': "(['project', 'ref'],)"},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']", 'related_name': "'+'"}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'references'"}),
'ref': ('django.db.models.fields.BigIntegerField', [], {})
},
'users.role': {
'Meta': {'object_name': 'Role', 'ordering': "['order', 'slug']", 'unique_together': "(('slug', 'project'),)"},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'null': 'True', 'default': '[]', 'dbtype': "'text'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'roles'"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'})
},
'users.user': {
'Meta': {'object_name': 'User', 'ordering': "['username']"},
'bio': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
'color': ('django.db.models.fields.CharField', [], {'blank': 'True', 'default': "'#7d4751'", 'max_length': '9'}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'blank': 'True', 'default': "''", 'max_length': '20'}),
'default_timezone': ('django.db.models.fields.CharField', [], {'blank': 'True', 'default': "''", 'max_length': '20'}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75'}),
'email_token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'max_length': '200'}),
'full_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '256'}),
'github_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'new_email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'null': 'True', 'max_length': '75'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'null': 'True', 'max_length': '500'}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'null': 'True', 'default': 'None', 'max_length': '200'}),
'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'})
}
}
complete_apps = ['references']

View File

@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.db import models
from django.utils import timezone
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.generic import GenericForeignKey
@ -31,7 +32,7 @@ class Reference(models.Model):
object_id = models.PositiveIntegerField()
ref = models.BigIntegerField()
content_object = GenericForeignKey("content_type", "object_id")
created_at = models.DateTimeField(auto_now_add=True)
created_at = models.DateTimeField(default=timezone.now)
project = models.ForeignKey("projects.Project", null=False,
blank=False, related_name="references")

View File

@ -0,0 +1,291 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Task.subject'
db.alter_column('tasks_task', 'subject', self.gf('django.db.models.fields.TextField')())
# Changing field 'Task.modified_date'
db.alter_column('tasks_task', 'modified_date', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'Task.created_date'
db.alter_column('tasks_task', 'created_date', self.gf('django.db.models.fields.DateTimeField')())
def backwards(self, orm):
# Changing field 'Task.subject'
db.alter_column('tasks_task', 'subject', self.gf('django.db.models.fields.CharField')(max_length=500))
# Changing field 'Task.modified_date'
db.alter_column('tasks_task', 'modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True))
# Changing field 'Task.created_date'
db.alter_column('tasks_task', 'created_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
models = {
'issues.issue': {
'Meta': {'ordering': "['project', '-created_date']", 'object_name': 'Issue'},
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['users.User']", 'blank': 'True', 'related_name': "'issues_assigned_to_me'"}),
'blocked_note': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'finished_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['milestones.Milestone']", 'blank': 'True', 'related_name': "'issues'"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['users.User']", 'blank': 'True', 'related_name': "'owned_issues'"}),
'priority': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.Priority']"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.Project']"}),
'ref': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'default': 'None', 'db_index': 'True', 'blank': 'True'}),
'severity': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.Severity']"}),
'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.IssueStatus']"}),
'subject': ('django.db.models.fields.TextField', [], {}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': 'None', 'dbtype': "'text'", 'blank': 'True'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issues'", 'to': "orm['projects.IssueType']"}),
'version': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'null': 'True', 'related_name': "'issues_issue+'", 'to': "orm['users.User']", 'blank': 'True', 'symmetrical': 'False'})
},
'milestones.milestone': {
'Meta': {'ordering': "['project', 'created_date']", 'unique_together': "[('name', 'project'), ('slug', 'project')]", 'object_name': 'Milestone'},
'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'disponibility': ('django.db.models.fields.FloatField', [], {'null': 'True', 'default': '0.0', 'blank': 'True'}),
'estimated_finish': ('django.db.models.fields.DateField', [], {}),
'estimated_start': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '200'}),
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'related_name': "'owned_milestones'", 'to': "orm['users.User']", 'blank': 'True'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'milestones'", 'to': "orm['projects.Project']"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '250', 'blank': 'True'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'null': 'True', 'related_name': "'milestones_milestone+'", 'to': "orm['users.User']", 'blank': 'True', 'symmetrical': 'False'})
},
'projects.issuestatus': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'IssueStatus'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_statuses'", 'to': "orm['projects.Project']"})
},
'projects.issuetype': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'IssueType'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_types'", 'to': "orm['projects.Project']"})
},
'projects.membership': {
'Meta': {'ordering': "['project', 'user__full_name', 'user__username', 'user__email', 'email']", 'unique_together': "(('user', 'project'),)", 'object_name': 'Membership'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'null': 'True', 'default': 'None', 'max_length': '255', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invited_by_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['projects.Project']"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['users.Role']"}),
'token': ('django.db.models.fields.CharField', [], {'null': 'True', 'default': 'None', 'max_length': '60', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['users.User']", 'blank': 'True', 'related_name': "'memberships'"})
},
'projects.points': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'Points'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'points'", 'to': "orm['projects.Project']"}),
'value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'default': 'None', 'blank': 'True'})
},
'projects.priority': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'Priority'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'priorities'", 'to': "orm['projects.Project']"})
},
'projects.project': {
'Meta': {'ordering': "['name']", 'object_name': 'Project'},
'anon_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': '[]', 'dbtype': "'text'", 'blank': 'True'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['projects.ProjectTemplate']", 'blank': 'True', 'related_name': "'projects'"}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'related_name': "'+'", 'to': "orm['projects.IssueStatus']", 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL'}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'related_name': "'+'", 'to': "orm['projects.IssueType']", 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL'}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'related_name': "'+'", 'to': "orm['projects.Points']", 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL'}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'related_name': "'+'", 'to': "orm['projects.Priority']", 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL'}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'related_name': "'+'", 'to': "orm['projects.Severity']", 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL'}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'related_name': "'+'", 'to': "orm['projects.TaskStatus']", 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL'}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'null': 'True', 'related_name': "'+'", 'to': "orm['projects.UserStoryStatus']", 'blank': 'True', 'unique': 'True', 'on_delete': 'models.SET_NULL'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'through': "orm['projects.Membership']", 'to': "orm['users.User']", 'symmetrical': 'False', 'related_name': "'projects'"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '250'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_projects'", 'to': "orm['users.User']"}),
'public_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': '[]', 'dbtype': "'text'", 'blank': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '250', 'blank': 'True'}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': 'None', 'dbtype': "'text'", 'blank': 'True'}),
'tags_colors': ('djorm_pgarray.fields.TextArrayField', [], {'default': '[]', 'dimension': '2', 'dbtype': "'text'", 'blank': 'True'}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'default': '0', 'blank': 'True'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'null': 'True', 'max_length': '250', 'blank': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'null': 'True', 'max_length': '250', 'blank': 'True'})
},
'projects.projecttemplate': {
'Meta': {'ordering': "['name']", 'object_name': 'ProjectTemplate'},
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '250', 'blank': 'True'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'null': 'True', 'max_length': '250', 'blank': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'null': 'True', 'max_length': '250', 'blank': 'True'})
},
'projects.severity': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'Severity'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'severities'", 'to': "orm['projects.Project']"})
},
'projects.taskstatus': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'TaskStatus'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_statuses'", 'to': "orm['projects.Project']"})
},
'projects.userstorystatus': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'UserStoryStatus'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'us_statuses'", 'to': "orm['projects.Project']"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'default': 'None', 'blank': 'True'})
},
'tasks.task': {
'Meta': {'ordering': "['project', 'created_date']", 'object_name': 'Task'},
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['users.User']", 'blank': 'True', 'related_name': "'tasks_assigned_to_me'"}),
'blocked_note': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'finished_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_iocaine': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['milestones.Milestone']", 'blank': 'True', 'related_name': "'tasks'"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['users.User']", 'blank': 'True', 'related_name': "'owned_tasks'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'to': "orm['projects.Project']"}),
'ref': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'default': 'None', 'db_index': 'True', 'blank': 'True'}),
'status': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tasks'", 'to': "orm['projects.TaskStatus']"}),
'subject': ('django.db.models.fields.TextField', [], {}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': 'None', 'dbtype': "'text'", 'blank': 'True'}),
'user_story': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'related_name': "'tasks'", 'to': "orm['userstories.UserStory']", 'blank': 'True'}),
'version': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'null': 'True', 'related_name': "'tasks_task+'", 'to': "orm['users.User']", 'blank': 'True', 'symmetrical': 'False'})
},
'users.role': {
'Meta': {'ordering': "['order', 'slug']", 'unique_together': "(('slug', 'project'),)", 'object_name': 'Role'},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': '[]', 'dbtype': "'text'", 'blank': 'True'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'roles'", 'to': "orm['projects.Project']"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '250', 'blank': 'True'})
},
'users.user': {
'Meta': {'ordering': "['username']", 'object_name': 'User'},
'bio': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'color': ('django.db.models.fields.CharField', [], {'default': "'#e98dda'", 'max_length': '9', 'blank': 'True'}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20', 'blank': 'True'}),
'default_timezone': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '20', 'blank': 'True'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_token': ('django.db.models.fields.CharField', [], {'null': 'True', 'default': 'None', 'max_length': '200', 'blank': 'True'}),
'full_name': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'github_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'new_email': ('django.db.models.fields.EmailField', [], {'null': 'True', 'max_length': '75', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'null': 'True', 'max_length': '500', 'blank': 'True'}),
'token': ('django.db.models.fields.CharField', [], {'null': 'True', 'default': 'None', 'max_length': '200', 'blank': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'userstories.rolepoints': {
'Meta': {'ordering': "['user_story', 'role']", 'unique_together': "(('user_story', 'role'),)", 'object_name': 'RolePoints'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'points': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'role_points'", 'to': "orm['projects.Points']"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'role_points'", 'to': "orm['users.Role']"}),
'user_story': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'role_points'", 'to': "orm['userstories.UserStory']"})
},
'userstories.userstory': {
'Meta': {'ordering': "['project', 'order', 'ref']", 'object_name': 'UserStory'},
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['users.User']", 'blank': 'True', 'related_name': "'userstories_assigned_to_me'"}),
'blocked_note': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'client_requirement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'finish_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
'generated_from_issue': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'related_name': "'generated_user_stories'", 'to': "orm['issues.Issue']", 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'default': 'None', 'to': "orm['milestones.Milestone']", 'blank': 'True', 'related_name': "'user_stories'", 'on_delete': 'models.SET_NULL'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '100'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'related_name': "'owned_user_stories'", 'to': "orm['users.User']", 'blank': 'True', 'on_delete': 'models.SET_NULL'}),
'points': ('django.db.models.fields.related.ManyToManyField', [], {'through': "orm['userstories.RolePoints']", 'to': "orm['projects.Points']", 'symmetrical': 'False', 'related_name': "'userstories'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_stories'", 'to': "orm['projects.Project']"}),
'ref': ('django.db.models.fields.BigIntegerField', [], {'null': 'True', 'default': 'None', 'db_index': 'True', 'blank': 'True'}),
'status': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'related_name': "'user_stories'", 'to': "orm['projects.UserStoryStatus']", 'blank': 'True', 'on_delete': 'models.SET_NULL'}),
'subject': ('django.db.models.fields.TextField', [], {}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': 'None', 'dbtype': "'text'", 'blank': 'True'}),
'team_requirement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'version': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'null': 'True', 'related_name': "'userstories_userstory+'", 'to': "orm['users.User']", 'blank': 'True', 'symmetrical': 'False'})
}
}
complete_apps = ['tasks']

View File

@ -46,9 +46,10 @@ class Task(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, models.M
milestone = models.ForeignKey("milestones.Milestone", null=True, blank=True,
default=None, related_name="tasks",
verbose_name=_("milestone"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
created_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("created date"),
default=timezone.now)
modified_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("modified date"))
finished_date = models.DateTimeField(null=True, blank=True,
verbose_name=_("finished date"))
@ -61,6 +62,7 @@ class Task(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, models.M
attachments = generic.GenericRelation("attachments.Attachment")
is_iocaine = models.BooleanField(default=False, null=False, blank=True,
verbose_name=_("is iocaine"))
_importing = None
class Meta:
verbose_name = "task"
@ -71,6 +73,12 @@ class Task(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, models.M
("view_task", "Can view task"),
)
def save(self, *args, **kwargs):
if not self._importing:
self.modified_date = timezone.now()
return super().save(*args, **kwargs)
def __str__(self):
return "({1}) {0}".format(self.ref, self.subject)

View File

@ -35,6 +35,7 @@ class TaskSerializer(serializers.ModelSerializer):
class Meta:
model = models.Task
read_only_fields = ('id', 'ref', 'created_date', 'modified_date')
def get_comment(self, obj):
return ""
@ -72,5 +73,5 @@ class TasksBulkSerializer(ProjectExistsValidator, SprintExistsValidator, TaskSta
project_id = serializers.IntegerField()
sprint_id = serializers.IntegerField()
status_id = serializers.IntegerField(required=False)
us_id = serializers.IntegerField()
us_id = serializers.IntegerField(required=False)
bulk_tasks = serializers.CharField()

View File

@ -0,0 +1,269 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'UserStory.subject'
db.alter_column('userstories_userstory', 'subject', self.gf('django.db.models.fields.TextField')())
# Changing field 'UserStory.modified_date'
db.alter_column('userstories_userstory', 'modified_date', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'UserStory.created_date'
db.alter_column('userstories_userstory', 'created_date', self.gf('django.db.models.fields.DateTimeField')())
def backwards(self, orm):
# Changing field 'UserStory.subject'
db.alter_column('userstories_userstory', 'subject', self.gf('django.db.models.fields.CharField')(max_length=500))
# Changing field 'UserStory.modified_date'
db.alter_column('userstories_userstory', 'modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True))
# Changing field 'UserStory.created_date'
db.alter_column('userstories_userstory', 'created_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
models = {
'issues.issue': {
'Meta': {'ordering': "['project', '-created_date']", 'object_name': 'Issue'},
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'to': "orm['users.User']", 'default': 'None', 'related_name': "'issues_assigned_to_me'"}),
'blocked_note': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'finished_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'to': "orm['milestones.Milestone']", 'default': 'None', 'related_name': "'issues'"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'to': "orm['users.User']", 'default': 'None', 'related_name': "'owned_issues'"}),
'priority': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Priority']", 'related_name': "'issues'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issues'"}),
'ref': ('django.db.models.fields.BigIntegerField', [], {'blank': 'True', 'db_index': 'True', 'default': 'None', 'null': 'True'}),
'severity': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Severity']", 'related_name': "'issues'"}),
'status': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.IssueStatus']", 'related_name': "'issues'"}),
'subject': ('django.db.models.fields.TextField', [], {}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'default': 'None', 'null': 'True'}),
'type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.IssueType']", 'related_name': "'issues'"}),
'version': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'null': 'True', 'to': "orm['users.User']", 'related_name': "'issues_issue+'"})
},
'milestones.milestone': {
'Meta': {'ordering': "['project', 'created_date']", 'unique_together': "[('name', 'project'), ('slug', 'project')]", 'object_name': 'Milestone'},
'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'disponibility': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'default': '0.0', 'null': 'True'}),
'estimated_finish': ('django.db.models.fields.DateField', [], {}),
'estimated_start': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'db_index': 'True', 'max_length': '200'}),
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'to': "orm['users.User']", 'related_name': "'owned_milestones'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'milestones'"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'null': 'True', 'to': "orm['users.User']", 'related_name': "'milestones_milestone+'"})
},
'projects.issuestatus': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'IssueStatus'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issue_statuses'"})
},
'projects.issuetype': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'IssueType'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'issue_types'"})
},
'projects.membership': {
'Meta': {'ordering': "['project', 'user__full_name', 'user__username', 'user__email', 'email']", 'unique_together': "(('user', 'project'),)", 'object_name': 'Membership'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '255', 'default': 'None', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invited_by_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'memberships'"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.Role']", 'related_name': "'memberships'"}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '60', 'default': 'None', 'null': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'to': "orm['users.User']", 'default': 'None', 'related_name': "'memberships'"})
},
'projects.points': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'Points'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'points'"}),
'value': ('django.db.models.fields.FloatField', [], {'blank': 'True', 'default': 'None', 'null': 'True'})
},
'projects.priority': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'Priority'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'priorities'"})
},
'projects.project': {
'Meta': {'ordering': "['name']", 'object_name': 'Project'},
'anon_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'default': '[]', 'null': 'True'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'to': "orm['projects.ProjectTemplate']", 'default': 'None', 'related_name': "'projects'"}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'unique': 'True', 'to': "orm['projects.IssueStatus']", 'null': 'True'}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'unique': 'True', 'to': "orm['projects.IssueType']", 'null': 'True'}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'unique': 'True', 'to': "orm['projects.Points']", 'null': 'True'}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'unique': 'True', 'to': "orm['projects.Priority']", 'null': 'True'}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'unique': 'True', 'to': "orm['projects.Severity']", 'null': 'True'}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'unique': 'True', 'to': "orm['projects.TaskStatus']", 'null': 'True'}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'+'", 'unique': 'True', 'to': "orm['projects.UserStoryStatus']", 'null': 'True'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['users.User']", 'through': "orm['projects.Membership']", 'related_name': "'projects'"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '250'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.User']", 'related_name': "'owned_projects'"}),
'public_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'default': '[]', 'null': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'unique': 'True', 'max_length': '250'}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'default': 'None', 'null': 'True'}),
'tags_colors': ('djorm_pgarray.fields.TextArrayField', [], {'dimension': '2', 'blank': 'True', 'dbtype': "'text'", 'default': '[]'}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'default': '0', 'null': 'True'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'})
},
'projects.projecttemplate': {
'Meta': {'ordering': "['name']", 'object_name': 'ProjectTemplate'},
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'unique': 'True', 'max_length': '250'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '250', 'null': 'True'})
},
'projects.severity': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'Severity'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'severities'"})
},
'projects.taskstatus': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'TaskStatus'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'task_statuses'"})
},
'projects.userstorystatus': {
'Meta': {'ordering': "['project', 'order', 'name']", 'unique_together': "(('project', 'name'),)", 'object_name': 'UserStoryStatus'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'us_statuses'"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'default': 'None', 'null': 'True'})
},
'users.role': {
'Meta': {'ordering': "['order', 'slug']", 'unique_together': "(('slug', 'project'),)", 'object_name': 'Role'},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'default': '[]', 'null': 'True'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'roles'"}),
'slug': ('django.db.models.fields.SlugField', [], {'blank': 'True', 'max_length': '250'})
},
'users.user': {
'Meta': {'ordering': "['username']", 'object_name': 'User'},
'bio': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
'color': ('django.db.models.fields.CharField', [], {'blank': 'True', 'default': "'#8d6dd6'", 'max_length': '9'}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'blank': 'True', 'default': "''", 'max_length': '20'}),
'default_timezone': ('django.db.models.fields.CharField', [], {'blank': 'True', 'default': "''", 'max_length': '20'}),
'email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75'}),
'email_token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '200', 'default': 'None', 'null': 'True'}),
'full_name': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '256'}),
'github_id': ('django.db.models.fields.IntegerField', [], {'blank': 'True', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'new_email': ('django.db.models.fields.EmailField', [], {'blank': 'True', 'max_length': '75', 'null': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'blank': 'True', 'max_length': '500', 'null': 'True'}),
'token': ('django.db.models.fields.CharField', [], {'blank': 'True', 'max_length': '200', 'default': 'None', 'null': 'True'}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
'userstories.rolepoints': {
'Meta': {'ordering': "['user_story', 'role']", 'unique_together': "(('user_story', 'role'),)", 'object_name': 'RolePoints'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'points': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Points']", 'related_name': "'role_points'"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['users.Role']", 'related_name': "'role_points'"}),
'user_story': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['userstories.UserStory']", 'related_name': "'role_points'"})
},
'userstories.userstory': {
'Meta': {'ordering': "['project', 'order', 'ref']", 'object_name': 'UserStory'},
'assigned_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'to': "orm['users.User']", 'default': 'None', 'related_name': "'userstories_assigned_to_me'"}),
'blocked_note': ('django.db.models.fields.TextField', [], {'blank': 'True', 'default': "''"}),
'client_requirement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'description': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'finish_date': ('django.db.models.fields.DateTimeField', [], {'blank': 'True', 'null': 'True'}),
'generated_from_issue': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'null': 'True', 'to': "orm['issues.Issue']", 'related_name': "'generated_user_stories'"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_archived': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_blocked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'milestone': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'on_delete': 'models.SET_NULL', 'related_name': "'user_stories'", 'to': "orm['milestones.Milestone']", 'default': 'None', 'null': 'True'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '100'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'on_delete': 'models.SET_NULL', 'blank': 'True', 'null': 'True', 'to': "orm['users.User']", 'related_name': "'owned_user_stories'"}),
'points': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Points']", 'through': "orm['userstories.RolePoints']", 'related_name': "'userstories'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']", 'related_name': "'user_stories'"}),
'ref': ('django.db.models.fields.BigIntegerField', [], {'blank': 'True', 'db_index': 'True', 'default': 'None', 'null': 'True'}),
'status': ('django.db.models.fields.related.ForeignKey', [], {'on_delete': 'models.SET_NULL', 'blank': 'True', 'null': 'True', 'to': "orm['projects.UserStoryStatus']", 'related_name': "'user_stories'"}),
'subject': ('django.db.models.fields.TextField', [], {}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'blank': 'True', 'dbtype': "'text'", 'default': 'None', 'null': 'True'}),
'team_requirement': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'version': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'blank': 'True', 'null': 'True', 'to': "orm['users.User']", 'related_name': "'userstories_userstory+'"})
}
}
complete_apps = ['userstories']

View File

@ -19,6 +19,7 @@ from django.contrib.contenttypes import generic
from django.conf import settings
from django.dispatch import receiver
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from taiga.base.tags import TaggedMixin
from taiga.base.utils.slug import ref_uniquely
@ -75,9 +76,10 @@ class UserStory(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, mod
verbose_name=_("points"))
order = models.PositiveSmallIntegerField(null=False, blank=False, default=100,
verbose_name=_("order"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
created_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("created date"),
default=timezone.now)
modified_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("modified date"))
finish_date = models.DateTimeField(null=True, blank=True,
verbose_name=_("finish date"))
@ -95,6 +97,7 @@ class UserStory(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, mod
generated_from_issue = models.ForeignKey("issues.Issue", null=True, blank=True,
related_name="generated_user_stories",
verbose_name=_("generated from issue"))
_importing = None
class Meta:
verbose_name = "user story"
@ -105,6 +108,12 @@ class UserStory(OCCModelMixin, WatchedModelMixin, BlockedMixin, TaggedMixin, mod
("view_userstory", "Can view user story"),
)
def save(self, *args, **kwargs):
if not self._importing:
self.modified_date = timezone.now()
super().save(*args, **kwargs)
def __str__(self):
return "({1}) {0}".format(self.ref, self.subject)

View File

@ -50,6 +50,7 @@ class UserStorySerializer(serializers.ModelSerializer):
class Meta:
model = models.UserStory
depth = 0
read_only_fields = ('created_date', 'modified_date')
def save_object(self, obj, **kwargs):
role_points = obj._related_data.pop("role_points", None)

View File

@ -0,0 +1,211 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'WikiPage.created_date'
db.alter_column('wiki_wikipage', 'created_date', self.gf('django.db.models.fields.DateTimeField')())
# Changing field 'WikiPage.modified_date'
db.alter_column('wiki_wikipage', 'modified_date', self.gf('django.db.models.fields.DateTimeField')())
def backwards(self, orm):
# Changing field 'WikiPage.created_date'
db.alter_column('wiki_wikipage', 'created_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
# Changing field 'WikiPage.modified_date'
db.alter_column('wiki_wikipage', 'modified_date', self.gf('django.db.models.fields.DateTimeField')(auto_now=True))
models = {
'projects.issuestatus': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'IssueStatus'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_statuses'", 'to': "orm['projects.Project']"})
},
'projects.issuetype': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'IssueType'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'issue_types'", 'to': "orm['projects.Project']"})
},
'projects.membership': {
'Meta': {'unique_together': "(('user', 'project'),)", 'ordering': "['project', 'user__full_name', 'user__username', 'user__email', 'email']", 'object_name': 'Membership'},
'created_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'null': 'True', 'default': 'None', 'blank': 'True', 'max_length': '255'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invited_by_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'is_owner': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['projects.Project']"}),
'role': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'memberships'", 'to': "orm['users.Role']"}),
'token': ('django.db.models.fields.CharField', [], {'null': 'True', 'default': 'None', 'blank': 'True', 'max_length': '60'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'related_name': "'memberships'", 'default': 'None', 'blank': 'True', 'to': "orm['users.User']"})
},
'projects.points': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Points'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'points'", 'to': "orm['projects.Project']"}),
'value': ('django.db.models.fields.FloatField', [], {'null': 'True', 'default': 'None', 'blank': 'True'})
},
'projects.priority': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Priority'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'priorities'", 'to': "orm['projects.Project']"})
},
'projects.project': {
'Meta': {'object_name': 'Project', 'ordering': "['name']"},
'anon_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': '[]', 'blank': 'True', 'dbtype': "'text'"}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'creation_template': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'related_name': "'projects'", 'default': 'None', 'blank': 'True', 'to': "orm['projects.ProjectTemplate']"}),
'default_issue_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'blank': 'True', 'unique': 'True', 'to': "orm['projects.IssueStatus']", 'null': 'True'}),
'default_issue_type': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'blank': 'True', 'unique': 'True', 'to': "orm['projects.IssueType']", 'null': 'True'}),
'default_points': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'blank': 'True', 'unique': 'True', 'to': "orm['projects.Points']", 'null': 'True'}),
'default_priority': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'blank': 'True', 'unique': 'True', 'to': "orm['projects.Priority']", 'null': 'True'}),
'default_severity': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'blank': 'True', 'unique': 'True', 'to': "orm['projects.Severity']", 'null': 'True'}),
'default_task_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'blank': 'True', 'unique': 'True', 'to': "orm['projects.TaskStatus']", 'null': 'True'}),
'default_us_status': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'+'", 'on_delete': 'models.SET_NULL', 'blank': 'True', 'unique': 'True', 'to': "orm['projects.UserStoryStatus']", 'null': 'True'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_private': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['users.User']", 'related_name': "'projects'", 'through': "orm['projects.Membership']", 'symmetrical': 'False'}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250', 'unique': 'True'}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'owned_projects'", 'to': "orm['users.User']"}),
'public_permissions': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': '[]', 'blank': 'True', 'dbtype': "'text'"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '250', 'blank': 'True', 'unique': 'True'}),
'tags': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': 'None', 'blank': 'True', 'dbtype': "'text'"}),
'tags_colors': ('djorm_pgarray.fields.TextArrayField', [], {'default': '[]', 'dimension': '2', 'blank': 'True', 'dbtype': "'text'"}),
'total_milestones': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'default': '0', 'blank': 'True'}),
'total_story_points': ('django.db.models.fields.FloatField', [], {'default': '0'}),
'videoconferences': ('django.db.models.fields.CharField', [], {'null': 'True', 'max_length': '250', 'blank': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'null': 'True', 'max_length': '250', 'blank': 'True'})
},
'projects.projecttemplate': {
'Meta': {'object_name': 'ProjectTemplate', 'ordering': "['name']"},
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_options': ('django_pgjson.fields.JsonField', [], {}),
'default_owner_role': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'description': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_backlog_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_issues_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_kanban_activated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_wiki_activated': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'issue_statuses': ('django_pgjson.fields.JsonField', [], {}),
'issue_types': ('django_pgjson.fields.JsonField', [], {}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'points': ('django_pgjson.fields.JsonField', [], {}),
'priorities': ('django_pgjson.fields.JsonField', [], {}),
'roles': ('django_pgjson.fields.JsonField', [], {}),
'severities': ('django_pgjson.fields.JsonField', [], {}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '250', 'blank': 'True', 'unique': 'True'}),
'task_statuses': ('django_pgjson.fields.JsonField', [], {}),
'us_statuses': ('django_pgjson.fields.JsonField', [], {}),
'videoconferences': ('django.db.models.fields.CharField', [], {'null': 'True', 'max_length': '250', 'blank': 'True'}),
'videoconferences_salt': ('django.db.models.fields.CharField', [], {'null': 'True', 'max_length': '250', 'blank': 'True'})
},
'projects.severity': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'Severity'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'severities'", 'to': "orm['projects.Project']"})
},
'projects.taskstatus': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'TaskStatus'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'task_statuses'", 'to': "orm['projects.Project']"})
},
'projects.userstorystatus': {
'Meta': {'unique_together': "(('project', 'name'),)", 'ordering': "['project', 'order', 'name']", 'object_name': 'UserStoryStatus'},
'color': ('django.db.models.fields.CharField', [], {'default': "'#999999'", 'max_length': '20'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'us_statuses'", 'to': "orm['projects.Project']"}),
'wip_limit': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'default': 'None', 'blank': 'True'})
},
'users.role': {
'Meta': {'unique_together': "(('slug', 'project'),)", 'ordering': "['order', 'slug']", 'object_name': 'Role'},
'computable': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
'permissions': ('djorm_pgarray.fields.TextArrayField', [], {'null': 'True', 'default': '[]', 'blank': 'True', 'dbtype': "'text'"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'roles'", 'to': "orm['projects.Project']"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '250', 'blank': 'True'})
},
'users.user': {
'Meta': {'object_name': 'User', 'ordering': "['username']"},
'bio': ('django.db.models.fields.TextField', [], {'default': "''", 'blank': 'True'}),
'color': ('django.db.models.fields.CharField', [], {'default': "'#7a4665'", 'blank': 'True', 'max_length': '9'}),
'colorize_tags': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'default_language': ('django.db.models.fields.CharField', [], {'default': "''", 'blank': 'True', 'max_length': '20'}),
'default_timezone': ('django.db.models.fields.CharField', [], {'default': "''", 'blank': 'True', 'max_length': '20'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'email_token': ('django.db.models.fields.CharField', [], {'null': 'True', 'default': 'None', 'blank': 'True', 'max_length': '200'}),
'full_name': ('django.db.models.fields.CharField', [], {'max_length': '256', 'blank': 'True'}),
'github_id': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'new_email': ('django.db.models.fields.EmailField', [], {'null': 'True', 'max_length': '75', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'photo': ('django.db.models.fields.files.FileField', [], {'null': 'True', 'max_length': '500', 'blank': 'True'}),
'token': ('django.db.models.fields.CharField', [], {'null': 'True', 'default': 'None', 'blank': 'True', 'max_length': '200'}),
'username': ('django.db.models.fields.CharField', [], {'max_length': '30', 'unique': 'True'})
},
'wiki.wikilink': {
'Meta': {'unique_together': "(('project', 'href'),)", 'ordering': "['project', 'order']", 'object_name': 'WikiLink'},
'href': ('django.db.models.fields.SlugField', [], {'max_length': '500'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '1'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wiki_links'", 'to': "orm['projects.Project']"}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'wiki.wikipage': {
'Meta': {'unique_together': "(('project', 'slug'),)", 'ordering': "['project', 'slug']", 'object_name': 'WikiPage'},
'content': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
'created_date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'last_modifier': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'related_name': "'last_modified_wiki_pages'", 'blank': 'True', 'to': "orm['users.User']"}),
'modified_date': ('django.db.models.fields.DateTimeField', [], {}),
'owner': ('django.db.models.fields.related.ForeignKey', [], {'null': 'True', 'related_name': "'owned_wiki_pages'", 'blank': 'True', 'to': "orm['users.User']"}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'wiki_pages'", 'to': "orm['projects.Project']"}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '500'}),
'version': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
'watchers': ('django.db.models.fields.related.ManyToManyField', [], {'null': 'True', 'related_name': "'wiki_wikipage+'", 'to': "orm['users.User']", 'blank': 'True', 'symmetrical': 'False'})
}
}
complete_apps = ['wiki']

View File

@ -18,6 +18,7 @@ from django.db import models
from django.contrib.contenttypes import generic
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from taiga.projects.notifications import WatchedModelMixin
from taiga.projects.occ import OCCModelMixin
@ -33,11 +34,13 @@ class WikiPage(OCCModelMixin, WatchedModelMixin, models.Model):
related_name="owned_wiki_pages", verbose_name=_("owner"))
last_modifier = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True,
related_name="last_modified_wiki_pages", verbose_name=_("last modifier"))
created_date = models.DateTimeField(auto_now_add=True, null=False, blank=False,
verbose_name=_("created date"))
modified_date = models.DateTimeField(auto_now=True, null=False, blank=False,
created_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("created date"),
default=timezone.now)
modified_date = models.DateTimeField(null=False, blank=False,
verbose_name=_("modified date"))
attachments = generic.GenericRelation("attachments.Attachment")
_importing = None
class Meta:
verbose_name = "wiki page"
@ -51,6 +54,12 @@ class WikiPage(OCCModelMixin, WatchedModelMixin, models.Model):
def __str__(self):
return "project {0} - {1}".format(self.project_id, self.slug)
def save(self, *args, **kwargs):
if not self._importing:
self.modified_date = timezone.now()
return super().save(*args, **kwargs)
class WikiLink(models.Model):
project = models.ForeignKey("projects.Project", null=False, blank=False,

View File

@ -29,6 +29,7 @@ class WikiPageSerializer(serializers.ModelSerializer):
class Meta:
model = models.WikiPage
read_only_fields = ('modified_date', 'created_date')
def get_html(self, obj):
return mdrender(obj.project, obj.content)

View File

@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Changing field 'Timeline.created'
db.alter_column('timeline_timeline', 'created', self.gf('django.db.models.fields.DateTimeField')())
def backwards(self, orm):
# Changing field 'Timeline.created'
db.alter_column('timeline_timeline', 'created', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True))
models = {
'contenttypes.contenttype': {
'Meta': {'object_name': 'ContentType', 'db_table': "'django_content_type'", 'unique_together': "(('app_label', 'model'),)", 'ordering': "('name',)"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'timeline.timeline': {
'Meta': {'object_name': 'Timeline', 'index_together': "[('content_type', 'object_id', 'namespace')]"},
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
'created': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'data': ('django_pgjson.fields.JsonField', [], {'blank': 'False', 'null': 'False'}),
'event_type': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'namespace': ('django.db.models.fields.SlugField', [], {'max_length': '50', 'default': "'default'"}),
'object_id': ('django.db.models.fields.PositiveIntegerField', [], {})
}
}
complete_apps = ['timeline']

View File

@ -16,6 +16,7 @@
from django.db import models
from django_pgjson.fields import JsonField
from django.utils import timezone
from django.core.exceptions import ValidationError
@ -30,7 +31,7 @@ class Timeline(models.Model):
namespace = models.SlugField(default="default")
event_type = models.SlugField()
data = JsonField()
created = models.DateTimeField(auto_now_add=True)
created = models.DateTimeField(default=timezone.now)
def save(self, *args, **kwargs):
if self.id: