diff --git a/symposion/boxes/models.py b/symposion/boxes/models.py
index 4eb2a019..3c13edd1 100644
--- a/symposion/boxes/models.py
+++ b/symposion/boxes/models.py
@@ -1,5 +1,6 @@
from django.db import models
from django.contrib.auth.models import User
+from django.utils.translation import ugettext_lazy as _
import reversion
@@ -8,17 +9,17 @@ from markitup.fields import MarkupField
class Box(models.Model):
- label = models.CharField(max_length=100, db_index=True)
+ label = models.CharField(max_length=100, db_index=True, verbose_name=_("Label"))
content = MarkupField(blank=True)
- created_by = models.ForeignKey(User, related_name="boxes")
- last_updated_by = models.ForeignKey(User, related_name="updated_boxes")
+ created_by = models.ForeignKey(User, related_name="boxes", verbose_name=_("Created by"))
+ last_updated_by = models.ForeignKey(User, related_name="updated_boxes", verbose_name=_("Last updated by"))
def __unicode__(self):
return self.label
class Meta:
- verbose_name_plural = "boxes"
-
+ verbose_name = _("Box")
+ verbose_name_plural = _("Boxes")
reversion.register(Box)
diff --git a/symposion/cms/models.py b/symposion/cms/models.py
index 25c1caea..a1955402 100644
--- a/symposion/cms/models.py
+++ b/symposion/cms/models.py
@@ -38,6 +38,10 @@ class Page(models.Model):
def __unicode__(self):
return self.title
+ class Meta:
+ verbose_name = _("page")
+ verbose_name_plural = _("pages")
+
@models.permalink
def get_absolute_url(self):
return ("cms_page", [self.path])
diff --git a/symposion/conference/apps.py b/symposion/conference/apps.py
index d7759eeb..7a330359 100644
--- a/symposion/conference/apps.py
+++ b/symposion/conference/apps.py
@@ -1,7 +1,8 @@
from django.apps import AppConfig
+from django.utils.translation import ugettext_lazy as _
class ConferenceConfig(AppConfig):
name = "symposion.conference"
label = "symposion_conference"
- verbose_name = "Symposion Conference"
+ verbose_name = _("Symposion Conference")
diff --git a/symposion/conference/models.py b/symposion/conference/models.py
index 582035b5..44e09627 100644
--- a/symposion/conference/models.py
+++ b/symposion/conference/models.py
@@ -12,14 +12,14 @@ class Conference(models.Model):
the full conference for a specific year, e.g. US PyCon 2012.
"""
- title = models.CharField(_("title"), max_length=100)
+ title = models.CharField(_("Title"), max_length=100)
# when the conference runs
- start_date = models.DateField(_("start date"), null=True, blank=True)
- end_date = models.DateField(_("end date"), null=True, blank=True)
+ start_date = models.DateField(_("Start date"), null=True, blank=True)
+ end_date = models.DateField(_("End date"), null=True, blank=True)
# timezone the conference is in
- timezone = TimeZoneField(_("timezone"), blank=True)
+ timezone = TimeZoneField(_("Timezone"), blank=True)
def __unicode__(self):
return self.title
@@ -49,14 +49,14 @@ class Section(models.Model):
scheduling process.
"""
- conference = models.ForeignKey(Conference, verbose_name=_("conference"))
+ conference = models.ForeignKey(Conference, verbose_name=_("Conference"))
- name = models.CharField(_("name"), max_length=100)
- slug = models.SlugField()
+ name = models.CharField(_("Name"), max_length=100)
+ slug = models.SlugField(verbose_name=_("Slug"))
# when the section runs
- start_date = models.DateField(_("start date"), null=True, blank=True)
- end_date = models.DateField(_("end date"), null=True, blank=True)
+ start_date = models.DateField(_("Start date"), null=True, blank=True)
+ end_date = models.DateField(_("End date"), null=True, blank=True)
def __unicode__(self):
return u"%s %s" % (self.conference, self.name)
diff --git a/symposion/forms.py b/symposion/forms.py
index 09fc5d4f..bdaf89ae 100644
--- a/symposion/forms.py
+++ b/symposion/forms.py
@@ -6,13 +6,14 @@ except ImportError:
from django import forms
import account.forms
+from django.utils.translation import ugettext_lazy as _
class SignupForm(account.forms.SignupForm):
- first_name = forms.CharField()
- last_name = forms.CharField()
- email_confirm = forms.EmailField(label="Confirm Email")
+ first_name = forms.CharField(label=_("First name"))
+ last_name = forms.CharField(label=_("Last name"))
+ email_confirm = forms.EmailField(label=_("Confirm Email"))
def __init__(self, *args, **kwargs):
super(SignupForm, self).__init__(*args, **kwargs)
@@ -32,7 +33,7 @@ class SignupForm(account.forms.SignupForm):
if email:
if email != email_confirm:
raise forms.ValidationError(
- "Email address must match previously typed email address")
+ _("Email address must match previously typed email address"))
return email_confirm
diff --git a/symposion/proposals/actions.py b/symposion/proposals/actions.py
index d059da81..1edb6528 100644
--- a/symposion/proposals/actions.py
+++ b/symposion/proposals/actions.py
@@ -1,10 +1,11 @@
import csv
from django.http import HttpResponse
+from django.utils.translation import ugettext_lazy as _
-def export_as_csv_action(description="Export selected objects as CSV file",
- fields=None, exclude=None, header=True):
+def export_as_csv_action(description=None, fields=None, exclude=None,
+ header=True):
"""
This function returns an export csv action
'fields' and 'exclude' work like in Django ModelForm
@@ -31,5 +32,7 @@ def export_as_csv_action(description="Export selected objects as CSV file",
writer.writerow(
[unicode(getattr(obj, field)).encode("utf-8", "replace") for field in field_names])
return response
+ if description is None:
+ description = _("Export selected objects as CSV file")
export_as_csv.short_description = description
return export_as_csv
diff --git a/symposion/proposals/apps.py b/symposion/proposals/apps.py
index 9a317525..c35c024c 100644
--- a/symposion/proposals/apps.py
+++ b/symposion/proposals/apps.py
@@ -1,7 +1,8 @@
from django.apps import AppConfig
+from django.utils.translation import ugettext_lazy as _
class ProposalsConfig(AppConfig):
name = "symposion.proposals"
label = "symposion_proposals"
- verbose_name = "Symposion Proposals"
+ verbose_name = _("Symposion Proposals")
diff --git a/symposion/proposals/forms.py b/symposion/proposals/forms.py
index 91c7e004..fada20be 100644
--- a/symposion/proposals/forms.py
+++ b/symposion/proposals/forms.py
@@ -1,5 +1,6 @@
from django import forms
from django.db.models import Q
+from django.utils.translation import ugettext_lazy as _
from symposion.proposals.models import SupportingDocument
# from markitup.widgets import MarkItUpWidget
@@ -11,7 +12,7 @@ from symposion.proposals.models import SupportingDocument
class AddSpeakerForm(forms.Form):
email = forms.EmailField(
- label="Email address of new speaker (use their email address, not yours)"
+ label=_("Email address of new speaker (use their email address, not yours)")
)
def __init__(self, *args, **kwargs):
@@ -26,7 +27,7 @@ class AddSpeakerForm(forms.Form):
).exists()
if exists:
raise forms.ValidationError(
- "This email address has already been invited to your talk proposal"
+ _("This email address has already been invited to your talk proposal")
)
return value
diff --git a/symposion/proposals/models.py b/symposion/proposals/models.py
index 7dea87cd..a8b4f8e0 100644
--- a/symposion/proposals/models.py
+++ b/symposion/proposals/models.py
@@ -31,12 +31,12 @@ class ProposalSection(models.Model):
* closed is NULL or False
"""
- section = models.OneToOneField(Section)
+ section = models.OneToOneField(Section, verbose_name=_("Section"))
- start = models.DateTimeField(null=True, blank=True)
- end = models.DateTimeField(null=True, blank=True)
- closed = models.NullBooleanField()
- published = models.NullBooleanField()
+ start = models.DateTimeField(null=True, blank=True, verbose_name=_("Start"))
+ end = models.DateTimeField(null=True, blank=True, verbose_name=_("End"))
+ closed = models.NullBooleanField(verbose_name=_("Closed"))
+ published = models.NullBooleanField(verbose_name=_("Published"))
@classmethod
def available(cls):
@@ -67,10 +67,10 @@ class ProposalKind(models.Model):
to distinguish the section as well as the kind.
"""
- section = models.ForeignKey(Section, related_name="proposal_kinds")
+ section = models.ForeignKey(Section, related_name="proposal_kinds", verbose_name=_("Section"))
name = models.CharField(_("Name"), max_length=100)
- slug = models.SlugField()
+ slug = models.SlugField(verbose_name=_("Slug"))
def __unicode__(self):
return self.name
@@ -80,9 +80,9 @@ class ProposalBase(models.Model):
objects = InheritanceManager()
- kind = models.ForeignKey(ProposalKind)
+ kind = models.ForeignKey(ProposalKind, verbose_name=_("Kind"))
- title = models.CharField(max_length=100)
+ title = models.CharField(max_length=100, verbose_name=_("Title"))
description = models.TextField(
_("Brief Description"),
max_length=400, # @@@ need to enforce 400 in UI
@@ -96,6 +96,7 @@ class ProposalBase(models.Model):
"target='_blank'>Markdown.")
)
additional_notes = MarkupField(
+ _("Addtional Notes"),
blank=True,
help_text=_("Anything else you'd like the program committee to know when making their "
"selection: your past experience, etc. This is not made public. Edit using "
@@ -105,8 +106,9 @@ class ProposalBase(models.Model):
submitted = models.DateTimeField(
default=now,
editable=False,
+ verbose_name=_("Submitted")
)
- speaker = models.ForeignKey(Speaker, related_name="proposals")
+ speaker = models.ForeignKey(Speaker, related_name="proposals", verbose_name=_("Speaker"))
def additional_speaker_validator(self, a_speaker):
if a_speaker.speaker.email == self.speaker.email:
@@ -115,8 +117,9 @@ class ProposalBase(models.Model):
raise ValidationError(_("%s has already been in speakers.") % a_speaker.speaker.email)
additional_speakers = models.ManyToManyField(Speaker, through="AdditionalSpeaker",
- blank=True, validators=[additional_speaker_validator])
- cancelled = models.BooleanField(default=False)
+ blank=True, verbose_name=_("Addtional speakers"),
+ validators=[additional_speaker_validator])
+ cancelled = models.BooleanField(default=False, verbose_name=_("Cancelled"))
def can_edit(self):
return True
@@ -170,12 +173,14 @@ class AdditionalSpeaker(models.Model):
(SPEAKING_STATUS_DECLINED, _("Declined")),
]
- speaker = models.ForeignKey(Speaker)
- proposalbase = models.ForeignKey(ProposalBase)
- status = models.IntegerField(choices=SPEAKING_STATUS, default=SPEAKING_STATUS_PENDING)
+ speaker = models.ForeignKey(Speaker, verbose_name=_("Speaker"))
+ proposalbase = models.ForeignKey(ProposalBase, verbose_name=_("Proposalbase"))
+ status = models.IntegerField(choices=SPEAKING_STATUS, default=SPEAKING_STATUS_PENDING, verbose_name=_("Status"))
class Meta:
unique_together = ("speaker", "proposalbase")
+ verbose_name = _("Addtional speaker")
+ verbose_name_plural = _("Additional speakers")
def __unicode__(self):
if self.status is self.SPEAKING_STATUS_PENDING:
@@ -194,14 +199,14 @@ def uuid_filename(instance, filename):
class SupportingDocument(models.Model):
- proposal = models.ForeignKey(ProposalBase, related_name="supporting_documents")
+ proposal = models.ForeignKey(ProposalBase, related_name="supporting_documents", verbose_name=_("Proposal"))
- uploaded_by = models.ForeignKey(User)
+ uploaded_by = models.ForeignKey(User, verbose_name=_("Uploaded by"))
- created_at = models.DateTimeField(default=now)
+ created_at = models.DateTimeField(default=now, verbose_name=_("Created at"))
- file = models.FileField(upload_to=uuid_filename)
- description = models.CharField(max_length=140)
+ file = models.FileField(upload_to=uuid_filename, verbose_name=_("File"))
+ description = models.CharField(max_length=140, verbose_name=_("Description"))
def download_url(self):
return reverse("proposal_document_download",
diff --git a/symposion/proposals/views.py b/symposion/proposals/views.py
index 46c3c1c6..1d07b23d 100644
--- a/symposion/proposals/views.py
+++ b/symposion/proposals/views.py
@@ -87,7 +87,7 @@ def proposal_submit_kind(request, kind_slug):
proposal.speaker = speaker_profile
proposal.save()
form.save_m2m()
- messages.success(request, "Proposal submitted.")
+ messages.success(request, _("Proposal submitted."))
if "add-speakers" in request.POST:
return redirect("proposal_speaker_manage", proposal.pk)
return redirect("dashboard")
diff --git a/symposion/reviews/apps.py b/symposion/reviews/apps.py
index 683b0c0f..80fab5c3 100644
--- a/symposion/reviews/apps.py
+++ b/symposion/reviews/apps.py
@@ -1,7 +1,8 @@
from django.apps import AppConfig
+from django.utils.translation import ugettext_lazy as _
class ReviewsConfig(AppConfig):
name = "symposion.reviews"
label = "symposion_reviews"
- verbose_name = "Symposion Reviews"
+ verbose_name = _("Symposion Reviews")
diff --git a/symposion/reviews/forms.py b/symposion/reviews/forms.py
index a705333c..f49cdab8 100644
--- a/symposion/reviews/forms.py
+++ b/symposion/reviews/forms.py
@@ -1,4 +1,5 @@
from django import forms
+from django.utils.translation import ugettext_lazy as _
from markitup.widgets import MarkItUpWidget
@@ -35,6 +36,7 @@ class SpeakerCommentForm(forms.ModelForm):
class BulkPresentationForm(forms.Form):
talk_ids = forms.CharField(
+ label=_("Talk ids"),
max_length=500,
- help_text="Provide a comma seperated list of talk ids to accept."
+ help_text=_("Provide a comma seperated list of talk ids to accept.")
)
diff --git a/symposion/reviews/models.py b/symposion/reviews/models.py
index 1537ae98..48602639 100644
--- a/symposion/reviews/models.py
+++ b/symposion/reviews/models.py
@@ -7,6 +7,7 @@ from django.db.models import Q
from django.db.models.signals import post_save
from django.contrib.auth.models import User
+from django.utils.translation import ugettext_lazy as _
from markitup.fields import MarkupField
@@ -31,10 +32,10 @@ class Votes(object):
MINUS_ONE = u"−1"
CHOICES = [
- (PLUS_ONE, u"+1 — Good proposal and I will argue for it to be accepted."),
- (PLUS_ZERO, u"+0 — OK proposal, but I will not argue for it to be accepted."),
- (MINUS_ZERO, u"−0 — Weak proposal, but I will not argue strongly against acceptance."),
- (MINUS_ONE, u"−1 — Serious issues and I will argue to reject this proposal."),
+ (PLUS_ONE, _("+1 — Good proposal and I will argue for it to be accepted.")),
+ (PLUS_ZERO, _("+0 — OK proposal, but I will not argue for it to be accepted.")),
+ (MINUS_ZERO, _("−0 — Weak proposal, but I will not argue strongly against acceptance.")),
+ (MINUS_ONE, _("−1 — Serious issues and I will argue to reject this proposal.")),
]
VOTES = Votes()
@@ -47,18 +48,18 @@ class ReviewAssignment(models.Model):
NUM_REVIEWERS = 3
ORIGIN_CHOICES = [
- (AUTO_ASSIGNED_INITIAL, "auto-assigned, initial"),
- (OPT_IN, "opted-in"),
- (AUTO_ASSIGNED_LATER, "auto-assigned, later"),
+ (AUTO_ASSIGNED_INITIAL, _("auto-assigned, initial")),
+ (OPT_IN, _("opted-in")),
+ (AUTO_ASSIGNED_LATER, _("auto-assigned, later")),
]
- proposal = models.ForeignKey(ProposalBase)
- user = models.ForeignKey(User)
+ proposal = models.ForeignKey(ProposalBase, verbose_name=_("Proposal"))
+ user = models.ForeignKey(User, verbose_name=_("User"))
- origin = models.IntegerField(choices=ORIGIN_CHOICES)
+ origin = models.IntegerField(choices=ORIGIN_CHOICES, verbose_name=_("Origin"))
- assigned_at = models.DateTimeField(default=datetime.now)
- opted_out = models.BooleanField(default=False)
+ assigned_at = models.DateTimeField(default=datetime.now, verbose_name=_("Assigned at"))
+ opted_out = models.BooleanField(default=False, verbose_name=_("Opted out"))
@classmethod
def create_assignments(cls, proposal, origin=AUTO_ASSIGNED_INITIAL):
@@ -92,27 +93,29 @@ class ReviewAssignment(models.Model):
class ProposalMessage(models.Model):
- proposal = models.ForeignKey(ProposalBase, related_name="messages")
- user = models.ForeignKey(User)
+ proposal = models.ForeignKey(ProposalBase, related_name="messages", verbose_name=_("Proposal"))
+ user = models.ForeignKey(User, verbose_name=_("User"))
- message = MarkupField()
- submitted_at = models.DateTimeField(default=datetime.now, editable=False)
+ message = MarkupField(verbose_name=_("Message"))
+ submitted_at = models.DateTimeField(default=datetime.now, editable=False, verbose_name=_("Submitted at"))
class Meta:
ordering = ["submitted_at"]
+ verbose_name = _("proposal message")
+ verbose_name_plural = _("proposal messages")
class Review(models.Model):
VOTES = VOTES
- proposal = models.ForeignKey(ProposalBase, related_name="reviews")
- user = models.ForeignKey(User)
+ proposal = models.ForeignKey(ProposalBase, related_name="reviews", verbose_name=_("Proposal"))
+ user = models.ForeignKey(User, verbose_name=_("User"))
# No way to encode "-0" vs. "+0" into an IntegerField, and I don't feel
# like some complicated encoding system.
- vote = models.CharField(max_length=2, blank=True, choices=VOTES.CHOICES)
- comment = MarkupField()
- submitted_at = models.DateTimeField(default=datetime.now, editable=False)
+ vote = models.CharField(max_length=2, blank=True, choices=VOTES.CHOICES, verbose_name=_("Vote"))
+ comment = MarkupField(verbose_name=_("Comment"))
+ submitted_at = models.DateTimeField(default=datetime.now, editable=False, verbose_name=_("Submitted at"))
def save(self, **kwargs):
if self.vote:
@@ -180,20 +183,26 @@ class Review(models.Model):
def section(self):
return self.proposal.kind.section.slug
+ class Meta:
+ verbose_name = _("review")
+ verbose_name_plural = _("reviews")
+
class LatestVote(models.Model):
VOTES = VOTES
- proposal = models.ForeignKey(ProposalBase, related_name="votes")
- user = models.ForeignKey(User)
+ proposal = models.ForeignKey(ProposalBase, related_name="votes", verbose_name=_("Proposal"))
+ user = models.ForeignKey(User, verbose_name=_("User"))
# No way to encode "-0" vs. "+0" into an IntegerField, and I don't feel
# like some complicated encoding system.
- vote = models.CharField(max_length=2, choices=VOTES.CHOICES)
- submitted_at = models.DateTimeField(default=datetime.now, editable=False)
+ vote = models.CharField(max_length=2, choices=VOTES.CHOICES, verbose_name=_("Vote"))
+ submitted_at = models.DateTimeField(default=datetime.now, editable=False, verbose_name=_("Submitted at"))
class Meta:
unique_together = [("proposal", "user")]
+ verbose_name = _("latest vote")
+ verbose_name_plural = _("latest votes")
def css_class(self):
return {
@@ -205,25 +214,25 @@ class LatestVote(models.Model):
class ProposalResult(models.Model):
- proposal = models.OneToOneField(ProposalBase, related_name="result")
- score = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("0.00"))
- comment_count = models.PositiveIntegerField(default=0)
- vote_count = models.PositiveIntegerField(default=0)
- plus_one = models.PositiveIntegerField(default=0)
- plus_zero = models.PositiveIntegerField(default=0)
- minus_zero = models.PositiveIntegerField(default=0)
- minus_one = models.PositiveIntegerField(default=0)
+ proposal = models.OneToOneField(ProposalBase, related_name="result", verbose_name=_("Proposal"))
+ score = models.DecimalField(max_digits=5, decimal_places=2, default=Decimal("0.00"), verbose_name=_("Score"))
+ comment_count = models.PositiveIntegerField(default=0, verbose_name=_("Comment count"))
+ vote_count = models.PositiveIntegerField(default=0, verbose_name=_("Vote count"))
+ plus_one = models.PositiveIntegerField(default=0, verbose_name=_("Plus one"))
+ plus_zero = models.PositiveIntegerField(default=0, verbose_name=_("Plus zero"))
+ minus_zero = models.PositiveIntegerField(default=0, verbose_name=_("Minus zero"))
+ minus_one = models.PositiveIntegerField(default=0, verbose_name=_("Minus one"))
accepted = models.NullBooleanField(choices=[
(True, "accepted"),
(False, "rejected"),
(None, "undecided"),
- ], default=None)
+ ], default=None, verbose_name=_("Accepted"))
status = models.CharField(max_length=20, choices=[
- ("accepted", "accepted"),
- ("rejected", "rejected"),
- ("undecided", "undecided"),
- ("standby", "standby"),
- ], default="undecided")
+ ("accepted", _("accepted")),
+ ("rejected", _("rejected")),
+ ("undecided", _("undecided")),
+ ("standby", _("standby")),
+ ], default="undecided", verbose_name=_("Status"))
@classmethod
def full_calculate(cls):
@@ -279,35 +288,47 @@ class ProposalResult(models.Model):
model = self.__class__
model._default_manager.filter(pk=self.pk).update(score=ProposalScoreExpression())
+ class Meta:
+ verbose_name = _("proposal_result")
+ verbose_name_plural = _("proposal_results")
+
class Comment(models.Model):
- proposal = models.ForeignKey(ProposalBase, related_name="comments")
- commenter = models.ForeignKey(User)
- text = MarkupField()
+ proposal = models.ForeignKey(ProposalBase, related_name="comments", verbose_name=_("Proposal"))
+ commenter = models.ForeignKey(User, verbose_name=_("Commenter"))
+ text = MarkupField(verbose_name=_("Text"))
# Or perhaps more accurately, can the user see this comment.
- public = models.BooleanField(choices=[(True, "public"), (False, "private")], default=False)
- commented_at = models.DateTimeField(default=datetime.now)
+ public = models.BooleanField(choices=[(True, _("public")), (False, _("private"))], default=False, verbose_name=_("Public"))
+ commented_at = models.DateTimeField(default=datetime.now, verbose_name=_("Commented at"))
+
+ class Meta:
+ verbose_name = _("comment")
+ verbose_name_plural = _("comments")
class NotificationTemplate(models.Model):
- label = models.CharField(max_length=100)
- from_address = models.EmailField()
- subject = models.CharField(max_length=100)
- body = models.TextField()
+ label = models.CharField(max_length=100, verbose_name=_("Label"))
+ from_address = models.EmailField(verbose_name=_("From address"))
+ subject = models.CharField(max_length=100, verbose_name=_("Subject"))
+ body = models.TextField(verbose_name=_("Body"))
+
+ class Meta:
+ verbose_name = _("notification template")
+ verbose_name_plural = _("notification templates")
class ResultNotification(models.Model):
- proposal = models.ForeignKey(ProposalBase, related_name="notifications")
+ proposal = models.ForeignKey(ProposalBase, related_name="notifications", verbose_name=_("Proposal"))
template = models.ForeignKey(NotificationTemplate, null=True, blank=True,
- on_delete=models.SET_NULL)
- timestamp = models.DateTimeField(default=datetime.now)
- to_address = models.EmailField()
- from_address = models.EmailField()
- subject = models.CharField(max_length=100)
- body = models.TextField()
+ on_delete=models.SET_NULL, verbose_name=_("Template"))
+ timestamp = models.DateTimeField(default=datetime.now, verbose_name=_("Timestamp"))
+ to_address = models.EmailField(verbose_name=_("To address"))
+ from_address = models.EmailField(verbose_name=_("From address"))
+ subject = models.CharField(max_length=100, verbose_name=_("Subject"))
+ body = models.TextField(verbose_name=_("Body"))
def recipients(self):
for speaker in self.proposal.speakers():
diff --git a/symposion/schedule/models.py b/symposion/schedule/models.py
index a0f88e81..efa2d24c 100644
--- a/symposion/schedule/models.py
+++ b/symposion/schedule/models.py
@@ -3,6 +3,7 @@ import datetime
from django.core.exceptions import ObjectDoesNotExist
from django.contrib.auth.models import User
from django.db import models
+from django.utils.translation import ugettext_lazy as _
from markitup.fields import MarkupField
@@ -13,21 +14,23 @@ from symposion.speakers.models import Speaker
class Schedule(models.Model):
- section = models.OneToOneField(Section)
- published = models.BooleanField(default=True)
- hidden = models.BooleanField("Hide schedule from overall conference view", default=False)
+ section = models.OneToOneField(Section, verbose_name=_("Section"))
+ published = models.BooleanField(default=True, verbose_name=_("Published"))
+ hidden = models.BooleanField(_("Hide schedule from overall conference view"), default=False)
def __unicode__(self):
return u"%s Schedule" % self.section
class Meta:
ordering = ["section"]
+ verbose_name = _('Schedule')
+ verbose_name_plural = _('Schedules')
class Day(models.Model):
- schedule = models.ForeignKey(Schedule)
- date = models.DateField()
+ schedule = models.ForeignKey(Schedule, verbose_name=_("Schedule"))
+ date = models.DateField(verbose_name=_("Date"))
def __unicode__(self):
return u"%s" % self.date
@@ -35,17 +38,23 @@ class Day(models.Model):
class Meta:
unique_together = [("schedule", "date")]
ordering = ["date"]
+ verbose_name = _("date")
+ verbose_name_plural = _("dates")
class Room(models.Model):
- schedule = models.ForeignKey(Schedule)
- name = models.CharField(max_length=65)
- order = models.PositiveIntegerField()
+ schedule = models.ForeignKey(Schedule, verbose_name=_("Schedule"))
+ name = models.CharField(max_length=65, verbose_name=_("Name"))
+ order = models.PositiveIntegerField(verbose_name=_("Order"))
def __unicode__(self):
return self.name
+ class Meta:
+ verbose_name = _("Room")
+ verbose_name_plural = _("Rooms")
+
class SlotKind(models.Model):
"""
@@ -53,20 +62,24 @@ class SlotKind(models.Model):
break, lunch, or X-minute talk.
"""
- schedule = models.ForeignKey(Schedule)
- label = models.CharField(max_length=50)
+ schedule = models.ForeignKey(Schedule, verbose_name=_("schedule"))
+ label = models.CharField(max_length=50, verbose_name=_("Label"))
def __unicode__(self):
return self.label
+ class Meta:
+ verbose_name = _("Slot kind")
+ verbose_name_plural = _("Slot kinds")
+
class Slot(models.Model):
- day = models.ForeignKey(Day)
- kind = models.ForeignKey(SlotKind)
- start = models.TimeField()
- end = models.TimeField()
- content_override = MarkupField(blank=True)
+ day = models.ForeignKey(Day, verbose_name=_("Day"))
+ kind = models.ForeignKey(SlotKind, verbose_name=_("Kind"))
+ start = models.TimeField(verbose_name=_("Start"))
+ end = models.TimeField(verbose_name=_("End"))
+ content_override = MarkupField(blank=True, verbose_name=_("Content override"))
def assign(self, content):
"""
@@ -130,6 +143,8 @@ class Slot(models.Model):
class Meta:
ordering = ["day", "start", "end"]
+ verbose_name = _("slot")
+ verbose_name_plural = _("slots")
class SlotRoom(models.Model):
@@ -137,8 +152,8 @@ class SlotRoom(models.Model):
Links a slot with a room.
"""
- slot = models.ForeignKey(Slot)
- room = models.ForeignKey(Room)
+ slot = models.ForeignKey(Slot, verbose_name=_("Slot"))
+ room = models.ForeignKey(Room, verbose_name=_("Room"))
def __unicode__(self):
return u"%s %s" % (self.room, self.slot)
@@ -146,20 +161,22 @@ class SlotRoom(models.Model):
class Meta:
unique_together = [("slot", "room")]
ordering = ["slot", "room__order"]
+ verbose_name = _("Slot room")
+ verbose_name_plural = _("Slot rooms")
class Presentation(models.Model):
- slot = models.OneToOneField(Slot, null=True, blank=True, related_name="content_ptr")
- title = models.CharField(max_length=100)
- description = MarkupField()
- abstract = MarkupField()
- speaker = models.ForeignKey(Speaker, related_name="presentations")
+ slot = models.OneToOneField(Slot, null=True, blank=True, related_name="content_ptr", verbose_name=_("Slot"))
+ title = models.CharField(max_length=100, verbose_name=_("Title"))
+ description = MarkupField(verbose_name=_("Description"))
+ abstract = MarkupField(verbose_name=_("Abstract"))
+ speaker = models.ForeignKey(Speaker, related_name="presentations", verbose_name=_("Speaker"))
additional_speakers = models.ManyToManyField(Speaker, related_name="copresentations",
- blank=True)
- cancelled = models.BooleanField(default=False)
- proposal_base = models.OneToOneField(ProposalBase, related_name="presentation")
- section = models.ForeignKey(Section, related_name="presentations")
+ blank=True, verbose_name=_("Additional speakers"))
+ cancelled = models.BooleanField(default=False, verbose_name=_("Cancelled"))
+ proposal_base = models.OneToOneField(ProposalBase, related_name="presentation", verbose_name=_("Proposal base"))
+ section = models.ForeignKey(Section, related_name="presentations", verbose_name=_("Section"))
@property
def number(self):
@@ -182,12 +199,14 @@ class Presentation(models.Model):
class Meta:
ordering = ["slot"]
+ verbose_name = _("presentation")
+ verbose_name_plural = _("presentations")
class Session(models.Model):
- day = models.ForeignKey(Day, related_name="sessions")
- slots = models.ManyToManyField(Slot, related_name="sessions")
+ day = models.ForeignKey(Day, related_name="sessions", verbose_name=_("Day"))
+ slots = models.ManyToManyField(Slot, related_name="sessions", verbose_name=_("Slots"))
def sorted_slots(self):
return self.slots.order_by("start")
@@ -217,6 +236,10 @@ class Session(models.Model):
)
return u""
+ class Meta:
+ verbose_name = _("Session")
+ verbose_name_plural = _("Sessions")
+
class SessionRole(models.Model):
@@ -224,19 +247,21 @@ class SessionRole(models.Model):
SESSION_ROLE_RUNNER = 2
SESSION_ROLE_TYPES = [
- (SESSION_ROLE_CHAIR, "Session Chair"),
- (SESSION_ROLE_RUNNER, "Session Runner"),
+ (SESSION_ROLE_CHAIR, _("Session Chair")),
+ (SESSION_ROLE_RUNNER, _("Session Runner")),
]
- session = models.ForeignKey(Session)
- user = models.ForeignKey(User)
- role = models.IntegerField(choices=SESSION_ROLE_TYPES)
- status = models.NullBooleanField()
+ session = models.ForeignKey(Session, verbose_name=_("Session"))
+ user = models.ForeignKey(User, verbose_name=_("User"))
+ role = models.IntegerField(choices=SESSION_ROLE_TYPES, verbose_name=_("Role"))
+ status = models.NullBooleanField(verbose_name=_("Status"))
submitted = models.DateTimeField(default=datetime.datetime.now)
class Meta:
unique_together = [("session", "user", "role")]
+ verbose_name = _("Session role")
+ verbose_name_plural = _("Session roles")
def __unicode__(self):
return u"%s %s: %s" % (self.user, self.session,
diff --git a/symposion/speakers/apps.py b/symposion/speakers/apps.py
index b4abf5d5..c772a12a 100644
--- a/symposion/speakers/apps.py
+++ b/symposion/speakers/apps.py
@@ -1,7 +1,8 @@
from django.apps import AppConfig
+from django.utils.translation import ugettext_lazy as _
class SpeakersConfig(AppConfig):
name = "symposion.speakers"
label = "symposion_speakers"
- verbose_name = "Symposion Speakers"
+ verbose_name = _("Symposion Speakers")
diff --git a/symposion/speakers/models.py b/symposion/speakers/models.py
index 0887ef45..48121f2c 100644
--- a/symposion/speakers/models.py
+++ b/symposion/speakers/models.py
@@ -1,4 +1,5 @@
import datetime
+from django.utils.translation import ugettext_lazy as _
from django.db import models
from django.core.urlresolvers import reverse
@@ -15,24 +16,28 @@ class Speaker(models.Model):
(2, "Two")
]
- user = models.OneToOneField(User, null=True, related_name="speaker_profile")
- name = models.CharField(max_length=100, help_text=("As you would like it to appear in the "
- "conference program."))
- biography = MarkupField(blank=True, help_text=("A little bit about you. Edit using "
- ""
- "Markdown."))
- photo = models.ImageField(upload_to="speaker_photos", blank=True)
- annotation = models.TextField() # staff only
- invite_email = models.CharField(max_length=200, unique=True, null=True, db_index=True)
- invite_token = models.CharField(max_length=40, db_index=True)
+ user = models.OneToOneField(User, null=True, related_name="speaker_profile", verbose_name=_("User"))
+ name = models.CharField(verbose_name=_("Name"), max_length=100,
+ help_text=_("As you would like it to appear in the"
+ " conference program."))
+ biography = MarkupField(blank=True, help_text=_("A little bit about you. Edit using "
+ ""
+ "Markdown."), verbose_name=_("Biography"))
+ photo = models.ImageField(upload_to="speaker_photos", blank=True, verbose_name=_("Photo"))
+ annotation = models.TextField(verbose_name=_("Annotation")) # staff only
+ invite_email = models.CharField(max_length=200, unique=True, null=True, db_index=True, verbose_name=_("Invite_email"))
+ invite_token = models.CharField(max_length=40, db_index=True, verbose_name=_("Invite token"))
created = models.DateTimeField(
default=datetime.datetime.now,
- editable=False
+ editable=False,
+ verbose_name=_("Created")
)
class Meta:
ordering = ['name']
+ verbose_name = _("Speaker")
+ verbose_name_plural = _("Speakers")
def __unicode__(self):
if self.user:
diff --git a/symposion/speakers/views.py b/symposion/speakers/views.py
index fbd4c57c..6d48c1dd 100644
--- a/symposion/speakers/views.py
+++ b/symposion/speakers/views.py
@@ -5,6 +5,7 @@ from django.shortcuts import render, redirect, get_object_or_404
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
+from django.utils.translation import ugettext_lazy as _
from symposion.proposals.models import ProposalBase
from symposion.speakers.forms import SpeakerForm
@@ -33,7 +34,7 @@ def speaker_create(request):
if not found:
speaker.invite_email = None
speaker.save()
- messages.success(request, "Speaker profile created.")
+ messages.success(request, _("Speaker profile created."))
return redirect("dashboard")
else:
form = SpeakerForm(initial={"name": request.user.get_full_name()})
@@ -61,7 +62,7 @@ def speaker_create_staff(request, pk):
speaker = form.save(commit=False)
speaker.user = user
speaker.save()
- messages.success(request, "Speaker profile created.")
+ messages.success(request, _("Speaker profile created."))
return redirect("user_list")
else:
form = SpeakerForm(initial={"name": user.get_full_name()})
@@ -88,8 +89,8 @@ def speaker_create_token(request, token):
).update(
speaker=existing_speaker
)
- messages.info(request, ("You have been associated with all pending "
- "talk proposals"))
+ messages.info(request, _("You have been associated with all pending "
+ "talk proposals"))
return redirect("dashboard")
else:
if not request.user.is_authenticated():
diff --git a/symposion/sponsorship/admin.py b/symposion/sponsorship/admin.py
index 77a84b8d..0e38ad04 100644
--- a/symposion/sponsorship/admin.py
+++ b/symposion/sponsorship/admin.py
@@ -61,9 +61,9 @@ class SponsorAdmin(admin.ModelAdmin):
# @@@ kinda ugly but using choices= on NullBooleanField is broken
form = super(SponsorAdmin, self).get_form(*args, **kwargs)
form.base_fields["active"].widget.choices = [
- (u"1", "unreviewed"),
- (u"2", "approved"),
- (u"3", "rejected")
+ ("1", _("unreviewed")),
+ ("2", _("approved")),
+ ("3", _("rejected"))
]
return form
diff --git a/symposion/sponsorship/apps.py b/symposion/sponsorship/apps.py
index 80bf19d1..92ee49cd 100644
--- a/symposion/sponsorship/apps.py
+++ b/symposion/sponsorship/apps.py
@@ -1,7 +1,9 @@
+from __future__ import unicode_literals
from django.apps import AppConfig
+from django.utils.translation import ugettext_lazy as _
class SponsorshipConfig(AppConfig):
name = "symposion.sponsorship"
label = "symposion_sponsorship"
- verbose_name = "Symposion Sponsorship"
+ verbose_name = _("Symposion Sponsorship")
diff --git a/symposion/sponsorship/forms.py b/symposion/sponsorship/forms.py
index 33b52f42..336f7ff5 100644
--- a/symposion/sponsorship/forms.py
+++ b/symposion/sponsorship/forms.py
@@ -2,6 +2,7 @@ from django import forms
from django.forms.models import inlineformset_factory, BaseInlineFormSet
from django.contrib.admin.widgets import AdminFileWidget
+from django.utils.translation import ugettext_lazy as _
from symposion.sponsorship.models import Sponsor, SponsorBenefit
@@ -61,7 +62,7 @@ class SponsorBenefitsInlineFormSet(BaseInlineFormSet):
# provide word limit as help_text
if form.instance.benefit.type == "text" and form.instance.max_words:
- form.fields[field].help_text = u"maximum %s words" % form.instance.max_words
+ form.fields[field].help_text = _("maximum %s words") % form.instance.max_words
# use admin file widget that shows currently uploaded file
if field == "upload":
diff --git a/symposion/sponsorship/models.py b/symposion/sponsorship/models.py
index d4161176..13bace02 100644
--- a/symposion/sponsorship/models.py
+++ b/symposion/sponsorship/models.py
@@ -16,16 +16,16 @@ from symposion.sponsorship.managers import SponsorManager
class SponsorLevel(models.Model):
- conference = models.ForeignKey(Conference, verbose_name=_("conference"))
- name = models.CharField(_("name"), max_length=100)
- order = models.IntegerField(_("order"), default=0)
- cost = models.PositiveIntegerField(_("cost"))
- description = models.TextField(_("description"), blank=True, help_text=_("This is private."))
+ conference = models.ForeignKey(Conference, verbose_name=_("Conference"))
+ name = models.CharField(_("Name"), max_length=100)
+ order = models.IntegerField(_("Order"), default=0)
+ cost = models.PositiveIntegerField(_("Cost"))
+ description = models.TextField(_("Description"), blank=True, help_text=_("This is private."))
class Meta:
ordering = ["conference", "order"]
- verbose_name = _("sponsor level")
- verbose_name_plural = _("sponsor levels")
+ verbose_name = _("Sponsor level")
+ verbose_name_plural = _("Sponsor levels")
def __unicode__(self):
return self.name
@@ -36,22 +36,22 @@ class SponsorLevel(models.Model):
class Sponsor(models.Model):
- applicant = models.ForeignKey(User, related_name="sponsorships", verbose_name=_("applicant"),
+ applicant = models.ForeignKey(User, related_name="sponsorships", verbose_name=_("Applicant"),
null=True)
name = models.CharField(_("Sponsor Name"), max_length=100)
display_url = models.URLField(_("display URL"), blank=True)
- external_url = models.URLField(_("external URL"))
- annotation = models.TextField(_("annotation"), blank=True)
+ external_url = models.URLField(_("External URL"))
+ annotation = models.TextField(_("Annotation"), blank=True)
contact_name = models.CharField(_("Contact Name"), max_length=100)
- contact_email = models.EmailField(_(u"Contact Email"))
+ contact_email = models.EmailField(_("Contact Email"))
level = models.ForeignKey(SponsorLevel, verbose_name=_("level"))
added = models.DateTimeField(_("added"), default=datetime.datetime.now)
active = models.BooleanField(_("active"), default=False)
# Denormalization (this assumes only one logo)
sponsor_logo = models.ForeignKey("SponsorBenefit", related_name="+", null=True, blank=True,
- editable=False)
+ editable=False, verbose_name=_("Sponsor logo"))
objects = SponsorManager()
@@ -59,8 +59,8 @@ class Sponsor(models.Model):
return self.name
class Meta:
- verbose_name = _("sponsor")
- verbose_name_plural = _("sponsors")
+ verbose_name = _("Sponsor")
+ verbose_name_plural = _("Sponsors")
def get_absolute_url(self):
if self.active:
@@ -151,12 +151,12 @@ post_save.connect(_check_level_change, sender=Sponsor)
BENEFIT_TYPE_CHOICES = [
- ("text", "Text"),
- ("richtext", "Rich Text"),
- ("file", "File"),
- ("weblogo", "Web Logo"),
- ("simple", "Simple"),
- ("option", "Option")
+ ("text", _("Text")),
+ ("file", _("File")),
+ ("richtext", _("Rich Text")),
+ ("weblogo", _("Web Logo")),
+ ("simple", _("Simple")),
+ ("option", _("Option"))
]
CONTENT_TYPE_CHOICES = [
@@ -168,10 +168,10 @@ CONTENT_TYPE_CHOICES = [
class Benefit(models.Model):
- name = models.CharField(_("name"), max_length=100)
- description = models.TextField(_("description"), blank=True)
- type = models.CharField(_("type"), choices=BENEFIT_TYPE_CHOICES,
- max_length=10, default="simple")
+ name = models.CharField(_("Name"), max_length=100)
+ description = models.TextField(_("Description"), blank=True)
+ type = models.CharField(_("Type"), choices=BENEFIT_TYPE_CHOICES, max_length=10,
+ default="simple")
content_type = models.CharField(_("content type"), choices=CONTENT_TYPE_CHOICES,
max_length=20, default="simple")
@@ -181,15 +181,17 @@ class Benefit(models.Model):
class BenefitLevel(models.Model):
- benefit = models.ForeignKey(Benefit, related_name="benefit_levels", verbose_name=_("benefit"))
- level = models.ForeignKey(SponsorLevel, related_name="benefit_levels", verbose_name=_("level"))
+ benefit = models.ForeignKey(Benefit, related_name="benefit_levels", verbose_name=_("Benefit"))
+ level = models.ForeignKey(SponsorLevel, related_name="benefit_levels", verbose_name=_("Level"))
# default limits for this benefit at given level
- max_words = models.PositiveIntegerField(_("max words"), blank=True, null=True)
- other_limits = models.CharField(_("other limits"), max_length=200, blank=True)
+ max_words = models.PositiveIntegerField(_("Max words"), blank=True, null=True)
+ other_limits = models.CharField(_("Other limits"), max_length=200, blank=True)
class Meta:
ordering = ["level"]
+ verbose_name = _("Benefit level")
+ verbose_name_plural = _("Benefit levels")
def __unicode__(self):
return u"%s - %s" % (self.level, self.benefit)
@@ -197,21 +199,23 @@ class BenefitLevel(models.Model):
class SponsorBenefit(models.Model):
- sponsor = models.ForeignKey(Sponsor, related_name="sponsor_benefits", verbose_name=_("sponsor"))
- benefit = models.ForeignKey(Benefit, related_name="sponsor_benefits", verbose_name=_("benefit"))
- active = models.BooleanField(default=True)
+ sponsor = models.ForeignKey(Sponsor, related_name="sponsor_benefits", verbose_name=_("Sponsor"))
+ benefit = models.ForeignKey(Benefit, related_name="sponsor_benefits", verbose_name=_("Benefit"))
+ active = models.BooleanField(default=True, verbose_name=_("Active"))
# Limits: will initially be set to defaults from corresponding BenefitLevel
- max_words = models.PositiveIntegerField(_("max words"), blank=True, null=True)
- other_limits = models.CharField(_("other limits"), max_length=200, blank=True)
+ max_words = models.PositiveIntegerField(_("Max words"), blank=True, null=True)
+ other_limits = models.CharField(_("Other limits"), max_length=200, blank=True)
# Data: zero or one of these fields will be used, depending on the
# type of the Benefit (text, file, or simple)
- text = models.TextField(_("text"), blank=True)
- upload = models.FileField(_("file"), blank=True, upload_to="sponsor_files")
+ text = models.TextField(_("Text"), blank=True)
+ upload = models.FileField(_("File"), blank=True, upload_to="sponsor_files")
class Meta:
ordering = ["-active"]
+ verbose_name = _("Sponsor benefit")
+ verbose_name_plural = _("Sponsor benefits")
def __unicode__(self):
return u"%s - %s" % (self.sponsor, self.benefit)
@@ -220,8 +224,8 @@ class SponsorBenefit(models.Model):
num_words = len(self.text.split())
if self.max_words and num_words > self.max_words:
raise ValidationError(
- "Sponsorship level only allows for %s words, you provided %d." % (
- self.max_words, num_words))
+ _("Sponsorship level only allows for %(word)s words, you provided %(num)d.") % {
+ "word": self.max_words, "num": num_words})
def data_fields(self):
"""
diff --git a/symposion/sponsorship/views.py b/symposion/sponsorship/views.py
index bf74ec3a..ae5597e7 100644
--- a/symposion/sponsorship/views.py
+++ b/symposion/sponsorship/views.py
@@ -6,16 +6,14 @@ import time
from zipfile import ZipFile, ZipInfo
from django.conf import settings
-
+from django.contrib import messages
+from django.contrib.admin.views.decorators import staff_member_required
+from django.contrib.auth.decorators import login_required
from django.http import Http404, HttpResponse
from django.shortcuts import render_to_response, redirect, get_object_or_404
from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _
-from django.contrib import messages
-from django.contrib.admin.views.decorators import staff_member_required
-from django.contrib.auth.decorators import login_required
-
from symposion.sponsorship.forms import SponsorApplicationForm, \
SponsorDetailsForm, SponsorBenefitsFormSet
from symposion.sponsorship.models import Benefit, Sponsor, SponsorBenefit, \
@@ -90,7 +88,7 @@ def sponsor_detail(request, pk):
form.save()
formset.save()
- messages.success(request, "Sponsorship details have been updated")
+ messages.success(request, _("Sponsorship details have been updated"))
return redirect("dashboard")
else:
diff --git a/symposion/teams/forms.py b/symposion/teams/forms.py
index a9080626..5ba8ccae 100644
--- a/symposion/teams/forms.py
+++ b/symposion/teams/forms.py
@@ -2,6 +2,7 @@ from django import forms
from django.utils.html import escape
from django.utils.safestring import mark_safe
+from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
@@ -10,8 +11,9 @@ from symposion.teams.models import Membership
class TeamInvitationForm(forms.Form):
- email = forms.EmailField(help_text=("email address must be that of an account on this "
- "conference site"))
+ email = forms.EmailField(label=_("Email"),
+ help_text=_("email address must be that of an account on this "
+ "conference site"))
def __init__(self, *args, **kwargs):
self.team = kwargs.pop("team")
@@ -22,7 +24,7 @@ class TeamInvitationForm(forms.Form):
email = cleaned_data.get("email")
if email is None:
- raise forms.ValidationError("valid email address required")
+ raise forms.ValidationError(_("valid email address required"))
try:
user = User.objects.get(email=email)
@@ -30,16 +32,16 @@ class TeamInvitationForm(forms.Form):
# eventually we can invite them but for now assume they are
# already on the site
raise forms.ValidationError(
- mark_safe("no account with email address %s found on this conference "
- "site" % escape(email)))
+ mark_safe(_("no account with email address %s found on this conference "
+ "site") % escape(email)))
state = self.team.get_state_for_user(user)
if state in ["member", "manager"]:
- raise forms.ValidationError("user already in team")
+ raise forms.ValidationError(_("user already in team"))
if state in ["invited"]:
- raise forms.ValidationError("user already invited to team")
+ raise forms.ValidationError(_("user already invited to team"))
self.user = user
self.state = state
diff --git a/symposion/teams/models.py b/symposion/teams/models.py
index 8c344cc4..fbbc4c45 100644
--- a/symposion/teams/models.py
+++ b/symposion/teams/models.py
@@ -5,30 +5,36 @@ from django.db import models
import reversion
from django.contrib.auth.models import Permission, User
+from django.utils.translation import ugettext_lazy as _
TEAM_ACCESS_CHOICES = [
- ("open", "open"),
- ("application", "by application"),
- ("invitation", "by invitation")
+ ("open", _("open")),
+ ("application", _("by application")),
+ ("invitation", _("by invitation"))
]
class Team(models.Model):
- slug = models.SlugField(unique=True)
- name = models.CharField(max_length=100)
- description = models.TextField(blank=True)
- access = models.CharField(max_length=20, choices=TEAM_ACCESS_CHOICES)
+ slug = models.SlugField(unique=True, verbose_name=_("Slug"))
+ name = models.CharField(max_length=100, verbose_name=_("Name"))
+ description = models.TextField(blank=True, verbose_name=_("Description"))
+ access = models.CharField(max_length=20, choices=TEAM_ACCESS_CHOICES,
+ verbose_name=_("Access"))
# member permissions
- permissions = models.ManyToManyField(Permission, blank=True, related_name="member_teams")
+ permissions = models.ManyToManyField(Permission, blank=True,
+ related_name="member_teams",
+ verbose_name=_("Permissions"))
# manager permissions
manager_permissions = models.ManyToManyField(Permission, blank=True,
- related_name="manager_teams")
+ related_name="manager_teams",
+ verbose_name=_("Manager permissions"))
- created = models.DateTimeField(default=datetime.datetime.now, editable=False)
+ created = models.DateTimeField(default=datetime.datetime.now,
+ editable=False, verbose_name=_("Created"))
@models.permalink
def get_absolute_url(self):
@@ -55,23 +61,32 @@ class Team(models.Model):
def managers(self):
return self.memberships.filter(state="manager")
+ class Meta:
+ verbose_name = _('Team')
+ verbose_name_plural = _('Teams')
MEMBERSHIP_STATE_CHOICES = [
- ("applied", "applied"),
- ("invited", "invited"),
- ("declined", "declined"),
- ("rejected", "rejected"),
- ("member", "member"),
- ("manager", "manager"),
+ ("applied", _("applied")),
+ ("invited", _("invited")),
+ ("declined", _("declined")),
+ ("rejected", _("rejected")),
+ ("member", _("member")),
+ ("manager", _("manager")),
]
class Membership(models.Model):
- user = models.ForeignKey(User, related_name="memberships")
- team = models.ForeignKey(Team, related_name="memberships")
- state = models.CharField(max_length=20, choices=MEMBERSHIP_STATE_CHOICES)
- message = models.TextField(blank=True)
+ user = models.ForeignKey(User, related_name="memberships",
+ verbose_name=_("User"))
+ team = models.ForeignKey(Team, related_name="memberships",
+ verbose_name=_("Team"))
+ state = models.CharField(max_length=20, choices=MEMBERSHIP_STATE_CHOICES,
+ verbose_name=_("State"))
+ message = models.TextField(blank=True, verbose_name=_("Message"))
+ class Meta:
+ verbose_name = _("Membership")
+ verbose_name_plural = _("Memberships")
reversion.register(Membership)
diff --git a/symposion/teams/views.py b/symposion/teams/views.py
index f45a0cba..a843be1c 100644
--- a/symposion/teams/views.py
+++ b/symposion/teams/views.py
@@ -5,6 +5,7 @@ from django.contrib.auth.decorators import login_required
from django.contrib import messages
from symposion.utils.mail import send_email
+from django.utils.translation import ugettext_lazy as _
from symposion.teams.forms import TeamInvitationForm
from symposion.teams.models import Team, Membership
@@ -66,7 +67,7 @@ def team_detail(request, slug):
if form.is_valid():
form.invite()
send_email([form.user.email], "teams_user_invited", context={"team": team})
- messages.success(request, "Invitation created.")
+ messages.success(request, _("Invitation created."))
return redirect("team_detail", slug=slug)
else:
form = TeamInvitationForm(team=team)
@@ -94,7 +95,7 @@ def team_join(request, slug):
membership, created = Membership.objects.get_or_create(team=team, user=request.user)
membership.state = "member"
membership.save()
- messages.success(request, "Joined team.")
+ messages.success(request, _("Joined team."))
return redirect("team_detail", slug=slug)
else:
return redirect("team_detail", slug=slug)
@@ -110,7 +111,7 @@ def team_leave(request, slug):
if can_leave(team, request.user) and request.method == "POST":
membership = Membership.objects.get(team=team, user=request.user)
membership.delete()
- messages.success(request, "Left team.")
+ messages.success(request, _("Left team."))
return redirect("dashboard")
else:
return redirect("team_detail", slug=slug)
@@ -132,7 +133,7 @@ def team_apply(request, slug):
"team": team,
"user": request.user
})
- messages.success(request, "Applied to join team.")
+ messages.success(request, _("Applied to join team."))
return redirect("team_detail", slug=slug)
else:
return redirect("team_detail", slug=slug)
@@ -148,7 +149,7 @@ def team_promote(request, pk):
if membership.state == "member":
membership.state = "manager"
membership.save()
- messages.success(request, "Promoted to manager.")
+ messages.success(request, _("Promoted to manager."))
return redirect("team_detail", slug=membership.team.slug)
@@ -162,7 +163,7 @@ def team_demote(request, pk):
if membership.state == "manager":
membership.state = "member"
membership.save()
- messages.success(request, "Demoted from manager.")
+ messages.success(request, _("Demoted from manager."))
return redirect("team_detail", slug=membership.team.slug)
@@ -176,7 +177,7 @@ def team_accept(request, pk):
if membership.state == "applied":
membership.state = "member"
membership.save()
- messages.success(request, "Accepted application.")
+ messages.success(request, _("Accepted application."))
return redirect("team_detail", slug=membership.team.slug)
@@ -190,5 +191,5 @@ def team_reject(request, pk):
if membership.state == "applied":
membership.state = "rejected"
membership.save()
- messages.success(request, "Rejected application.")
+ messages.success(request, _("Rejected application."))
return redirect("team_detail", slug=membership.team.slug)