Improvements
parent
bf512bfde7
commit
a227a95987
|
@ -12,5 +12,15 @@ admin.site.register(Profile, ProfileAdmin)
|
|||
|
||||
class RoleAdmin(admin.ModelAdmin):
|
||||
list_display = ["name"]
|
||||
filter_horizontal = ('permissions',)
|
||||
|
||||
def formfield_for_manytomany(self, db_field, request=None, **kwargs):
|
||||
if db_field.name == 'permissions':
|
||||
qs = kwargs.get('queryset', db_field.rel.to.objects)
|
||||
# Avoid a major performance hit resolving permission names which
|
||||
# triggers a content_type load:
|
||||
kwargs['queryset'] = qs.select_related('content_type')
|
||||
return super(RoleAdmin, self).formfield_for_manytomany(
|
||||
db_field, request=request, **kwargs)
|
||||
|
||||
admin.site.register(Role, RoleAdmin)
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from django.db import models
|
||||
from django.db.models.signals import post_save
|
||||
from django.db.models.signals import post_save, m2m_changed
|
||||
from django.dispatch import receiver
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.contrib.auth.models import User, Group
|
||||
|
||||
from greenmine.scrum.models import Project
|
||||
|
||||
class Profile(models.Model):
|
||||
user = models.OneToOneField("auth.User", related_name='profile')
|
||||
description = models.TextField(blank=True)
|
||||
|
@ -34,6 +36,10 @@ if not hasattr(Group, 'role'):
|
|||
field = models.ForeignKey(Role, blank=False, null=False, related_name='groups')
|
||||
field.contribute_to_class(Group, 'role')
|
||||
|
||||
if not hasattr(Group, 'project'):
|
||||
field = models.ForeignKey(Project, blank=False, null=False, related_name='groups')
|
||||
field.contribute_to_class(Group, 'project')
|
||||
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
def user_post_save(sender, instance, created, **kwargs):
|
||||
|
@ -45,9 +51,16 @@ def user_post_save(sender, instance, created, **kwargs):
|
|||
|
||||
@receiver(post_save, sender=Role)
|
||||
def role_post_save(sender, instance, **kwargs):
|
||||
from greenmine.profile.services import RoleGroupsService
|
||||
|
||||
"""
|
||||
Recalculate projects groups
|
||||
"""
|
||||
from greenmine.profile.services import RoleGroupsService
|
||||
RoleGroupsService().replicate_role_on_all_projects(instance)
|
||||
|
||||
@receiver(m2m_changed, sender=Role.permissions.through)
|
||||
def role_m2m_changed(sender, instance, **kwargs):
|
||||
"""
|
||||
Recalculate projects groups
|
||||
"""
|
||||
from greenmine.profile.services import RoleGroupsService
|
||||
RoleGroupsService().replicate_role_on_all_projects(instance)
|
||||
|
|
|
@ -12,13 +12,13 @@ class RoleGroupsService(object):
|
|||
|
||||
def replicate_all_roles_on_one_project(self, project):
|
||||
for role in Role.objects.all():
|
||||
group = Group(name="p%d-r%d" % (project.pk, role.pk), role=role)
|
||||
group = Group(name="p%d-r%d" % (project.pk, role.pk), role=role, project=project)
|
||||
group.save()
|
||||
self._replicate_role_permissions_on_group(role, group)
|
||||
|
||||
def _replicate_role_on_project_if_needed(self, role, project):
|
||||
if project.groups.filter(role=role).count() == 0:
|
||||
group = Group(name="p%d-r%d" % (project.pk, role.pk), role=role)
|
||||
group = Group(name="p%d-r%d" % (project.pk, role.pk), role=role, project=project)
|
||||
group.save()
|
||||
self._replicate_role_permissions_on_group(role, group)
|
||||
|
||||
|
@ -27,4 +27,3 @@ class RoleGroupsService(object):
|
|||
for permission in role.permissions.all():
|
||||
group.permissions.add(permission)
|
||||
group.save()
|
||||
|
||||
|
|
|
@ -2,48 +2,43 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from guardian.admin import GuardedModelAdmin
|
||||
import reversion
|
||||
|
||||
from greenmine.scrum.models import Project, ProjectExtras, \
|
||||
Milestone, UserStory, Change, ChangeAttachment, Task
|
||||
from greenmine.scrum.models import Project, Milestone, UserStory, Change, \
|
||||
ChangeAttachment, Task
|
||||
|
||||
|
||||
class ProjectAdmin(GuardedModelAdmin):
|
||||
class ProjectAdmin(GuardedModelAdmin, reversion.VersionAdmin):
|
||||
list_display = ["name", "owner"]
|
||||
|
||||
admin.site.register(Project, ProjectAdmin)
|
||||
|
||||
|
||||
class ProjectExtrasAdmin(admin.ModelAdmin):
|
||||
list_display = ["project"]
|
||||
|
||||
admin.site.register(ProjectExtras, ProjectExtrasAdmin)
|
||||
|
||||
|
||||
class MilestoneAdmin(admin.ModelAdmin):
|
||||
class MilestoneAdmin(reversion.VersionAdmin):
|
||||
list_display = ["name", "project", "owner"]
|
||||
|
||||
admin.site.register(Milestone, MilestoneAdmin)
|
||||
|
||||
|
||||
class UserStoryAdmin(admin.ModelAdmin):
|
||||
class UserStoryAdmin(reversion.VersionAdmin):
|
||||
list_display = ["ref", "milestone", "project", "owner"]
|
||||
|
||||
admin.site.register(UserStory, UserStoryAdmin)
|
||||
|
||||
|
||||
class ChangeAdmin(admin.ModelAdmin):
|
||||
class ChangeAdmin(reversion.VersionAdmin):
|
||||
list_display = ["id", "change_type", "project", "owner"]
|
||||
|
||||
admin.site.register(Change, ChangeAdmin)
|
||||
|
||||
|
||||
class ChangeAttachmentAdmin(admin.ModelAdmin):
|
||||
class ChangeAttachmentAdmin(reversion.VersionAdmin):
|
||||
list_display = ["id", "change", "owner"]
|
||||
|
||||
admin.site.register(ChangeAttachment, ChangeAttachmentAdmin)
|
||||
|
||||
|
||||
class TaskAdmin(admin.ModelAdmin):
|
||||
class TaskAdmin(reversion.VersionAdmin):
|
||||
list_display = ["subject", "type", "user_story"]
|
||||
|
||||
admin.site.register(Task, TaskAdmin)
|
||||
|
|
|
@ -24,27 +24,6 @@ class ProjectManager(models.Manager):
|
|||
return self.get(slug=slug)
|
||||
|
||||
|
||||
class ProjectExtras(models.Model):
|
||||
task_parser_re = models.CharField(max_length=1000, blank=True, null=True, default=None)
|
||||
sprints = models.IntegerField(default=1, blank=True, null=True)
|
||||
show_burndown = models.BooleanField(default=False, blank=True)
|
||||
show_burnup = models.BooleanField(default=False, blank=True)
|
||||
show_sprint_burndown = models.BooleanField(default=False, blank=True)
|
||||
total_story_points = models.FloatField(default=None, null=True)
|
||||
|
||||
def get_task_parse_re(self):
|
||||
re_str = settings.DEFAULT_TASK_PARSER_RE
|
||||
if self.task_parser_re:
|
||||
re_str = self.task_parser_re
|
||||
return re.compile(re_str, flags=re.U+re.M)
|
||||
|
||||
def parse_ustext(self, text):
|
||||
rx = self.get_task_parse_re()
|
||||
texts = rx.findall(text)
|
||||
for text in texts:
|
||||
yield text
|
||||
|
||||
|
||||
class Project(models.Model):
|
||||
uuid = models.CharField(max_length=40, unique=True, blank=True)
|
||||
name = models.CharField(max_length=250, unique=True)
|
||||
|
@ -55,17 +34,19 @@ class Project(models.Model):
|
|||
modified_date = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
owner = models.ForeignKey("auth.User", related_name="projects")
|
||||
groups = models.ManyToManyField('auth.Group',
|
||||
related_name="projects",
|
||||
null=True,
|
||||
blank=True)
|
||||
public = models.BooleanField(default=True)
|
||||
markup = models.CharField(max_length=10, choices=MARKUP_TYPE, default='md')
|
||||
extras = models.OneToOneField("ProjectExtras", related_name="project", null=True, default=None)
|
||||
|
||||
last_us_ref = models.BigIntegerField(null=True, default=0)
|
||||
last_task_ref = models.BigIntegerField(null=True, default=0)
|
||||
|
||||
task_parser_re = models.CharField(max_length=1000, blank=True, null=True, default=None)
|
||||
sprints = models.IntegerField(default=1, blank=True, null=True)
|
||||
show_burndown = models.BooleanField(default=False, blank=True)
|
||||
show_burnup = models.BooleanField(default=False, blank=True)
|
||||
show_sprint_burndown = models.BooleanField(default=False, blank=True)
|
||||
total_story_points = models.FloatField(default=None, null=True)
|
||||
|
||||
objects = ProjectManager()
|
||||
|
||||
class Meta:
|
||||
|
@ -120,13 +101,6 @@ class Project(models.Model):
|
|||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
def get_extras(self):
|
||||
if self.extras is None:
|
||||
self.extras = ProjectExtras.objects.create()
|
||||
self.__class__.objects.filter(pk=self.pk).update(extras=self.extras)
|
||||
|
||||
return self.extras
|
||||
|
||||
def natural_key(self):
|
||||
return (self.slug,)
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ from django.utils.translation import ugettext
|
|||
from django.template.loader import render_to_string
|
||||
from django.db.models.signals import post_save
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
|
||||
from greenmine.base import signals
|
||||
from greenmine.base.utils.auth import set_token
|
||||
from greenmine.base.mail.tasks import send_mail, send_bulk_mail
|
||||
|
@ -109,6 +107,7 @@ def mail_task_assigned(sender, task, user, **kwargs):
|
|||
subject = ugettext("Greenmine: task assigned")
|
||||
send_mail.delay(subject, template, [task.assigned_to.email])
|
||||
|
||||
|
||||
@receiver(post_save, sender=Project)
|
||||
def project_post_save(sender, instance, created, **kwargs):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue