Start adding coding rules
parent
86bc6d3bc5
commit
93daf68420
|
@ -0,0 +1,57 @@
|
|||
|
||||
============
|
||||
Coding rules
|
||||
============
|
||||
|
||||
Django models
|
||||
=============
|
||||
|
||||
* All model names in singular an CamelCase.
|
||||
|
||||
* All models have a **Meta** with at least:
|
||||
|
||||
- **verbose_name** and **verbose_name_plural**: unicode strings, lowercase, with spaces.
|
||||
- **ordering**: return a consistent order, using pk if no other unique field or combination exists.
|
||||
|
||||
* All models have **__unicode__** method, returning a human-readable, descriptive, short text.
|
||||
|
||||
* All fields have **verbose_name**. Also **help_text** if needed to fully explain the field meaning.
|
||||
|
||||
* All fields have explicit **blank** and **null** parameters. Use only those combinations, unless
|
||||
there a documented need of other thing:
|
||||
|
||||
Normal fields (IntegerField, DateField, ForeignKey, FileField...)
|
||||
- (optional) **null = True**, **blank = True**
|
||||
- (required) **null = False**, **blank = False**
|
||||
|
||||
Text fields (CharField, TextField, URLField...)
|
||||
- (optional) **null = False**, **blank = True**
|
||||
- (required) **null = False**, **blank = False**
|
||||
|
||||
Boolean fields:
|
||||
- (two values, T/F) **null = False**, **blank = True**
|
||||
- (three values, T/F/Null) **null = False**, **blank = True**
|
||||
|
||||
* Don't create text fields with **null = True**, unless you need to distinguish between empty string and None.
|
||||
|
||||
* Don't create boolean fields with **blank = False**, otherwise they could only be True.
|
||||
|
||||
Example::
|
||||
|
||||
class SomeClass(models.Model):
|
||||
name = models.CharField(max_length=100, null = False, blank = False, unique=True,
|
||||
verbose_name = _(u'name'))
|
||||
slug = models.SlugField(max_length=100, null = False, blank = False, unique=True,
|
||||
verbose_name = _(u'slug'),
|
||||
help_text = (u'Identifier of this object. Only letters, digits and underscore "_" allowed.'))
|
||||
text = models.TextField(null = False, blank = True,
|
||||
verbose_name = _(u'text'))
|
||||
|
||||
class Meta:
|
||||
verbose_name = _(u'some class')
|
||||
verbose_name_plural = _(u'some classes')
|
||||
ordering = ['name']
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
|
@ -30,6 +30,7 @@ Contents:
|
|||
|
||||
overview.rst
|
||||
settings.rst
|
||||
coding_rules.rst
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -62,9 +62,13 @@ class Role(models.Model):
|
|||
permissions = models.ManyToManyField('auth.Permission',
|
||||
verbose_name=_('permissions'), blank=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.name)
|
||||
class Meta:
|
||||
verbose_name = u'role'
|
||||
verbose_name_plural = u'roles'
|
||||
ordering = ['slug']
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
# Patch api view for correctly return 401 responses on
|
||||
|
|
|
@ -20,16 +20,22 @@ class Document(models.Model):
|
|||
null=True, blank=True)
|
||||
tags = DictField()
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.slug:
|
||||
self.slug = slugify(self.title, self.__class__)
|
||||
super(Document, self).save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
ordering = ['title']
|
||||
verbose_name = u'document'
|
||||
verbose_name_plural = u'document'
|
||||
ordering = ['project', 'title', 'id']
|
||||
permissions = (
|
||||
('can_download_from_my_projects', 'Can download the documents from my projects'),
|
||||
('can_download_from_other_projects', 'Can download the documents from other projects'),
|
||||
('can_change_owned_documents', 'Can modify owned documents'),
|
||||
('can_view_documents', 'Can modify owned documents'),
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.title
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.slug:
|
||||
self.slug = slugify(self.title, self.__class__)
|
||||
super(Document, self).save(*args, **kwargs)
|
||||
|
||||
|
|
|
@ -27,11 +27,17 @@ class Question(models.Model):
|
|||
tags = DictField()
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'question'
|
||||
verbose_name_plural = u'questions'
|
||||
ordering = ['project', 'subject', 'id']
|
||||
permissions = (
|
||||
('can_reply_question', 'Can reply questions'),
|
||||
('can_change_owned_question', 'Can modify owned questions'),
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.subject
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.slug:
|
||||
self.slug = slugify_uniquely(self.subject, self.__class__)
|
||||
|
@ -48,3 +54,12 @@ class QuestionResponse(models.Model):
|
|||
question = models.ForeignKey('Question', related_name='responses')
|
||||
owner = models.ForeignKey('base.User', related_name='questions_responses')
|
||||
tags = DictField()
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'question response'
|
||||
verbose_name_plural = u'question responses'
|
||||
ordering = ['question', 'created_date']
|
||||
|
||||
def __unicode__(self):
|
||||
return u'{0} - response {1}'.format(unicode(self.question), self.id)
|
||||
|
||||
|
|
|
@ -22,10 +22,13 @@ class Severity(models.Model):
|
|||
project = models.ForeignKey("Project", related_name="severities")
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'severity'
|
||||
verbose_name_plural = u'severities'
|
||||
ordering = ['project', 'name']
|
||||
unique_together = ('project', 'name')
|
||||
|
||||
def __unicode__(self):
|
||||
return u"project({0})/severity({1})".format(self.project.id, self.name)
|
||||
return u"project {0} - {1}".format(self.project_id, self.name)
|
||||
|
||||
|
||||
class IssueStatus(models.Model):
|
||||
|
@ -35,10 +38,13 @@ class IssueStatus(models.Model):
|
|||
project = models.ForeignKey("Project", related_name="issuestatuses")
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'issue status'
|
||||
verbose_name_plural = u'issue statuses'
|
||||
ordering = ['project', 'name']
|
||||
unique_together = ('project', 'name')
|
||||
|
||||
def __unicode__(self):
|
||||
return u"project({0})/issue-status({1})".format(self.project.id, self.name)
|
||||
return u"project {0} - {1}".format(self.project_id, self.name)
|
||||
|
||||
|
||||
class TaskStatus(models.Model):
|
||||
|
@ -49,10 +55,13 @@ class TaskStatus(models.Model):
|
|||
project = models.ForeignKey("Project", related_name="taskstatuses")
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'task status'
|
||||
verbose_name_plural = u'task statuses'
|
||||
ordering = ['project', 'name']
|
||||
unique_together = ('project', 'name')
|
||||
|
||||
def __unicode__(self):
|
||||
return u"project({0})/task-status({1})".format(self.project.id, self.name)
|
||||
return u"project {0} - {1}".format(self.project_id, self.name)
|
||||
|
||||
|
||||
class UserStoryStatus(models.Model):
|
||||
|
@ -62,10 +71,13 @@ class UserStoryStatus(models.Model):
|
|||
project = models.ForeignKey("Project", related_name="usstatuses")
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'user story status'
|
||||
verbose_name_plural = u'user story statuses'
|
||||
ordering = ['project', 'name']
|
||||
unique_together = ('project', 'name')
|
||||
|
||||
def __unicode__(self):
|
||||
return u"project({0})/us-status({1})".format(self.project.id, self.name)
|
||||
return u"project {0} - {1}".format(self.project_id, self.name)
|
||||
|
||||
|
||||
class Priority(models.Model):
|
||||
|
@ -74,10 +86,13 @@ class Priority(models.Model):
|
|||
project = models.ForeignKey("Project", related_name="priorities")
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'priority'
|
||||
verbose_name_plural = u'priorities'
|
||||
ordering = ['project', 'name']
|
||||
unique_together = ('project', 'name')
|
||||
|
||||
def __unicode__(self):
|
||||
return u"project({0})/priority({1})".format(self.project.id, self.name)
|
||||
return u"project {0} - {1}".format(self.project_id, self.name)
|
||||
|
||||
|
||||
class IssueType(models.Model):
|
||||
|
@ -87,10 +102,13 @@ class IssueType(models.Model):
|
|||
project = models.ForeignKey("Project", related_name="issuetypes")
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'issue type'
|
||||
verbose_name_plural = u'issue types'
|
||||
ordering = ['project', 'name']
|
||||
unique_together = ('project', 'name')
|
||||
|
||||
def __unicode__(self):
|
||||
return u"project({0})/type({1})".format(self.project.id, self.name)
|
||||
return u"project {0} - {1}".format(self.project_id, self.name)
|
||||
|
||||
|
||||
class Points(models.Model):
|
||||
|
@ -100,10 +118,13 @@ class Points(models.Model):
|
|||
project = models.ForeignKey("Project", related_name="points")
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'point'
|
||||
verbose_name_plural = u'points'
|
||||
ordering = ['project', 'name']
|
||||
unique_together = ('project', 'name')
|
||||
|
||||
def __unicode__(self):
|
||||
return u"project({0})/point({1})".format(self.project.id, self.name)
|
||||
return u"project {0} - {1}".format(self.project_id, self.name)
|
||||
|
||||
|
||||
class Membership(models.Model):
|
||||
|
@ -137,6 +158,9 @@ class Project(models.Model):
|
|||
tags = PickledObjectField()
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'project'
|
||||
verbose_name_plural = u'projects'
|
||||
ordering = ['name']
|
||||
permissions = (
|
||||
('can_list_projects', 'Can list projects'),
|
||||
('can_view_project', 'Can view project'),
|
||||
|
@ -147,7 +171,7 @@ class Project(models.Model):
|
|||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
return u"<Project %s>" % (self.slug)
|
||||
return u"<Project {0}>".format(self.id)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.slug:
|
||||
|
@ -174,16 +198,11 @@ class Milestone(models.Model):
|
|||
disponibility = models.FloatField(null=True, default=0.0)
|
||||
order = models.PositiveSmallIntegerField("Order", default=1)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.slug:
|
||||
self.slug = slugify_uniquely(self.name, self.__class__)
|
||||
|
||||
super(Milestone, self).save(*args, **kwargs)
|
||||
|
||||
class Meta:
|
||||
ordering = ['-created_date']
|
||||
verbose_name = u'milestone'
|
||||
verbose_name_plural = u'milestones'
|
||||
ordering = ['project', '-created_date']
|
||||
unique_together = ('name', 'project')
|
||||
|
||||
permissions = (
|
||||
('can_view_milestone', 'Can view milestones'),
|
||||
)
|
||||
|
@ -192,7 +211,13 @@ class Milestone(models.Model):
|
|||
return self.name
|
||||
|
||||
def __repr__(self):
|
||||
return u"<Milestone %s>" % (self.id)
|
||||
return u"<Milestone {0}>".format(self.id)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if not self.slug:
|
||||
self.slug = slugify_uniquely(self.name, self.__class__)
|
||||
|
||||
super(Milestone, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
class UserStory(models.Model):
|
||||
|
@ -223,7 +248,9 @@ class UserStory(models.Model):
|
|||
tags = PickledObjectField()
|
||||
|
||||
class Meta:
|
||||
ordering = ['order']
|
||||
verbose_name = u'user story'
|
||||
verbose_name_plural = u'user stories'
|
||||
ordering = ['project', 'order']
|
||||
unique_together = ('ref', 'project')
|
||||
permissions = (
|
||||
('can_comment_userstory', 'Can comment user stories'),
|
||||
|
@ -233,12 +260,12 @@ class UserStory(models.Model):
|
|||
('can_add_userstory_to_milestones', 'Can add user stories to milestones'),
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return u"({1}) {0}".format(self.ref, self.subject)
|
||||
|
||||
def __repr__(self):
|
||||
return u"<UserStory %s>" % (self.id)
|
||||
|
||||
def __unicode__(self):
|
||||
return u"{0} ({1})".format(self.subject, self.ref)
|
||||
|
||||
@property
|
||||
def is_closed(self):
|
||||
return self.status.is_closed
|
||||
|
@ -256,7 +283,15 @@ class Attachment(models.Model):
|
|||
attached_file = models.FileField(upload_to="files/msg", max_length=500,
|
||||
null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'attachment'
|
||||
verbose_name_plural = u'attachments'
|
||||
ordering = ['project', 'created_date']
|
||||
|
||||
def __unicode__(self):
|
||||
return u'content_type {0} - object_id {1} - attachment {2}'.format(
|
||||
self.content_type, self.object_id, self.id
|
||||
)
|
||||
|
||||
class Task(models.Model):
|
||||
uuid = models.CharField(max_length=40, unique=True, blank=True)
|
||||
|
@ -291,6 +326,9 @@ class Task(models.Model):
|
|||
tags = PickledObjectField()
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'task'
|
||||
verbose_name_plural = u'tasks'
|
||||
ordering = ['project', 'created_date']
|
||||
unique_together = ('ref', 'project')
|
||||
permissions = (
|
||||
('can_comment_task', 'Can comment tasks'),
|
||||
|
@ -304,7 +342,7 @@ class Task(models.Model):
|
|||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.subject
|
||||
return u"({1}) {0}".format(self.ref, self.subject)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.id:
|
||||
|
@ -348,6 +386,9 @@ class Issue(models.Model):
|
|||
tags = PickledObjectField()
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'issue'
|
||||
verbose_name_plural = u'issues'
|
||||
ordering = ['project', 'created_date']
|
||||
unique_together = ('ref', 'project')
|
||||
permissions = (
|
||||
('can_comment_issue', 'Can comment issues'),
|
||||
|
@ -360,7 +401,7 @@ class Issue(models.Model):
|
|||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.subject
|
||||
return u"({1}) {0}".format(self.ref, self.subject)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
if self.id:
|
||||
|
|
|
@ -16,12 +16,19 @@ class WikiPage(models.Model):
|
|||
created_date = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'wiki page'
|
||||
verbose_name_plural = u'wiki pages'
|
||||
ordering = ['project', 'slug']
|
||||
permissions = (
|
||||
('can_view_wikipage', 'Can modify owned wiki pages'),
|
||||
('can_change_owned_wikipage', 'Can modify owned wiki pages'),
|
||||
)
|
||||
|
||||
def __unicode__(self):
|
||||
return u"project {0} - {1}".format(self.project_id, self.subject)
|
||||
|
||||
|
||||
# TODO: why don't use scrum.Attachment?
|
||||
class WikiPageAttachment(models.Model):
|
||||
wikipage = models.ForeignKey('WikiPage', related_name='attachments')
|
||||
owner = models.ForeignKey("base.User", related_name="wikifiles")
|
||||
|
@ -29,3 +36,12 @@ class WikiPageAttachment(models.Model):
|
|||
modified_date = models.DateTimeField(auto_now_add=True)
|
||||
attached_file = models.FileField(upload_to="files/wiki", max_length=500,
|
||||
null=True, blank=True)
|
||||
|
||||
class Meta:
|
||||
verbose_name = u'wiki page attachment'
|
||||
verbose_name_plural = u'wiki page attachments'
|
||||
ordering = ['wikipage', 'created_date']
|
||||
|
||||
def __unicode__(self):
|
||||
return u"project {0} - page {1} - attachment {2}".format(self.wikipage.project_id, self.wikipage.subject, self.id)
|
||||
|
||||
|
|
Loading…
Reference in New Issue