Пример #1
0
class Post(models.Model):
    title = models.CharField(max_length=50)
    body = MarkupField('body of post')
    comment = MarkupField(escape_html=True, default_markup_type='markdown')

    def __unicode__(self):
        return self.title
Пример #2
0
class State(models.Model):
    abbreviation = models.CharField(max_length=2, primary_key=True)
    name = models.CharField(max_length=30)

    draws_congressional_lines = models.CharField(max_length=300, blank=True)
    draws_state_lines = models.CharField(max_length=300, blank=True)
    legislative_control = models.CharField(max_length=300, blank=True)
    gov_control = models.CharField(max_length=300, blank=True)
    latest_test_url = models.URLField(blank=True)
    map_drawing_links = models.CharField(max_length=300, blank = True)
    op_link = models.URLField(blank=True)
    status = models.PositiveIntegerField(
        choices=(
            (0, "Legislative action/public input"),
            (1, "Independent commission"),
            (2, "Other advisory/commission"),
            (3, "Potential reform by 2021"),
            (4, "Divided or potentially divided gov't."),
            (5, "Legal and legislative routes to reform"),
        ),
        default=0,
    )

    process = MarkupField(markup_type="markdown", blank=True)
    issues = MarkupField(markup_type="markdown", blank=True)
    actions = MarkupField(markup_type="markdown", blank=True)
    pitfalls = MarkupField(markup_type="markdown", blank=True)
    contacts = MarkupField(markup_type="markdown", blank=True)

    last_updated = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name
Пример #3
0
class Post(models.Model):
    title = models.CharField(max_length=50)
    body = MarkupField("body of post")
    comment = MarkupField(escape_html=True, default_markup_type="markdown")

    def __str__(self):
        return self.title
Пример #4
0
class SiteSettings(SingletonModel):
    class Meta:
        verbose_name_plural = "Site Settings"

    description = models.CharField(_('description'),
                                   max_length=300,
                                   blank=True)
    description_en = models.CharField(_('description (EN)'),
                                      max_length=300,
                                      blank=True)
    contact = models.CharField(_('contact'), max_length=300, blank=True)
    contact_en = models.CharField(_('contact (EN)'),
                                  max_length=300,
                                  blank=True)
    about_text = MarkupField(_('about_text'),
                             markup_type='markdown',
                             escape_html=True,
                             blank=True)
    about_text_en = MarkupField(_('about_text (EN)'),
                                markup_type='markdown',
                                escape_html=True,
                                blank=True)

    def __str__(self):
        return "Site Settings"
Пример #5
0
class GatheringCenter(TimeStampedModel):
    location_name = models.CharField(
        max_length=100,
        blank=True,
        default='',
        help_text=_('If this center has any special name')
        )
    address = models.CharField(max_length=255)
    city = models.ForeignKey(City)
    geoposition = GeopositionField(blank=True, null=True)
    description = MarkupField(
        blank=True,
        default='',
        default_markup_type='markdown',
        help_text=_('Any additional information about this specific gathering center')
        )
    published = models.BooleanField(blank=True, default=False)
    hours = models.TextField(blank=True)
    most_needed = MarkupField(
        blank=True,
        default='',
        default_markup_type='markdown',
    )
    # TODO add infomartion about what is needed the most

    def __unicode__(self):
        return '%s - %s' % (self.city, self.location_name or self.address)
Пример #6
0
class Article(models.Model):
    normal_field = MarkupField()
    markup_choices_field = MarkupField(markup_choices=(
        ('pandamarkup', lambda x: 'panda'),
        ('nomarkup', lambda x: x)))
    default_field = MarkupField(default_markup_type='markdown')
    markdown_field = MarkupField(markup_type='markdown')
Пример #7
0
class GatheringCenter(TimeStampedModel):
    location_name = models.CharField(
        max_length=100,
        blank=True,
        default='',
        help_text=_('If this center has any special name'))
    address = models.CharField(max_length=255)
    city = models.CharField(max_length=255, blank=True, null=True)
    region = models.ForeignKey(Region, null=True, blank=True)
    country = CountryField()
    geoposition = GeopositionField(blank=True, null=True)
    description = MarkupField(
        blank=True,
        default='',
        default_markup_type='markdown',
        escape_html=True,
        help_text=_(
            'Any additional information about this specific gathering center'))
    published = models.BooleanField(blank=True, default=False)
    hours = models.TextField(blank=True)
    most_needed = MarkupField(
        blank=True,
        default='',
        escape_html=True,
        default_markup_type='markdown',
    )
    author = models.ForeignKey(User, null=True)
    contact = models.CharField(max_length=255, null=True, blank=True)

    def __unicode__(self):
        return '%s - %s' % (self.city, self.location_name or self.address)

    def get_absolute_url(self):
        return reverse('gathering-center', args=(self.pk, ))
Пример #8
0
class Article(models.Model):
    normal_field = MarkupField()
    markup_choices_field = MarkupField(markup_choices=(
        ('pandamarkup', lambda x: 'panda'),
        ('nomarkup', lambda x: x),
        ('fancy', lambda x: x[::-1], 'Some fancy Markup'),  # String reverse
    ))
    default_field = MarkupField(default_markup_type='markdown')
    markdown_field = MarkupField(markup_type='markdown')
Пример #9
0
class Article(models.Model):
    normal_field = MarkupField()
    markup_choices_field = MarkupField(markup_choices=(
        ("pandamarkup", lambda x: "panda"),
        ("nomarkup", lambda x: x),
        ("fancy", lambda x: x[::-1], "Some fancy Markup"),  # String reverse
    ))
    default_field = MarkupField(default_markup_type="markdown")
    markdown_field = MarkupField(markup_type="markdown")
Пример #10
0
class Event(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, db_index=True)
    description = MarkupField(blank=True)
    overview = MarkupField(blank=True)
    start_date = models.DateField(db_index=True)
    end_date = models.DateField(blank=True, null=True, db_index=True)
    is_public = models.BooleanField(default=False, db_index=True)
    is_over = models.BooleanField(default=False, db_index=True)
    registration_is_open = models.BooleanField(default=False)
    registration_url = models.URLField(blank=True, default='')
    session_submission_is_open = models.BooleanField(default=False)

    label = models.CharField(max_length=64, default='event')
    session_label = models.CharField(max_length=64, default='session')
    session_length = TimedeltaField()

    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    created_by = models.ForeignKey(User, related_name='sked_events', blank=True, null=True)

    objects = EventManager()

    class Meta:
        ordering = ('-start_date', )

    def __unicode__(self):
        return self.name

    def get_absolute_url(self):
        try:
            return reverse('sked:session_list', kwargs={
                'event_slug': self.slug,
            })
        except Resolver404:
            return reverse('sked:session_list')

    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)[:50].rstrip('-')
        super(Event, self).save(*args, **kwargs)

    @property
    def url(self):
        return self.get_absolute_url()

    @property
    def is_current(self):
        return (self.pk == Event.objects.current().pk and not self.is_over)

    @property
    def is_upcoming(self):
        now = timezone.now()
        if self.start_date > now:
            return True
        return False
Пример #11
0
class Recipe(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=255)
    descr = MarkupField()
    ingredient = MarkupField()
    steps = MarkupField()
    added = models.DateTimeField()

    def __str__(self):
        return ('Recipe: %s' % self.title).encode('ascii', errors='replace')
Пример #12
0
class CodeSample(ContentManageable):
    code = MarkupField(default_markup_type=DEFAULT_MARKUP_TYPE, blank=True)
    copy = MarkupField(default_markup_type=DEFAULT_MARKUP_TYPE, blank=True)
    is_published = models.BooleanField(default=False, db_index=True)

    objects = CodeSampleQuerySet.as_manager()

    class Meta:
        verbose_name = 'sample'
        verbose_name_plural = 'samples'

    def __str__(self):
        return truncatechars(striptags(self.copy), 20)
Пример #13
0
class Experiment(TranslatableModel):
    objects = ExperimentManager()

    class Meta:
        ordering = ['order']

    translations = TranslatedFields(
        title=models.CharField(max_length=128),
        short_title=models.CharField(max_length=60, blank=True, default=''),
        description=models.TextField(),
        measurements=MarkupField(blank=True, default='',
                                 default_markup_type='plain'),
        introduction=MarkupField(blank=True, default='',
                                 default_markup_type='markdown'),
    )

    slug = models.SlugField(max_length=128, unique=True, db_index=True)
    thumbnail = models.ImageField(upload_to=experiment_thumbnail_upload_to)
    xpi_url = models.URLField()
    version = models.CharField(blank=True, max_length=128)
    order = models.IntegerField(default=0)
    changelog_url = models.URLField(blank=True)
    contribute_url = models.URLField(blank=True)
    bug_report_url = models.URLField(blank=True)
    discourse_url = models.URLField(blank=True)
    privacy_notice_url = models.URLField(blank=True)
    addon_id = models.CharField(max_length=500, blank=False,)
    gradient_start = ColorField(default='#e07634')
    gradient_stop = ColorField(default='#4cffa8')

    contributors = models.ManyToManyField(User, related_name='contributor')

    image_twitter = models.ImageField(upload_to=experiment_twitter_upload_to,
                                      help_text='560x300', null=True)
    image_facebook = models.ImageField(upload_to=experiment_facebook_upload_to,
                                       help_text='1200x1200, crop to 1200x630',
                                       null=True)

    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

    @cached_property
    def installation_count(self):
        return UserInstallation.objects.filter(experiment=self).count()

    def __str__(self):
        return self.title

    def natural_key(self):
        return (self.slug,)
Пример #14
0
class Book(models.Model):
    name = models.CharField(max_length=150)
    author = models.CharField(max_length=100)
    notes = MarkupField(default_markup_type='markdown', blank=True)
    date_added = models.DateTimeField(default=timezone.now)
    pages = models.IntegerField(null=True, blank=True)
    added_by = models.ForeignKey(User, on_delete=models.CASCADE)
    date_read = models.DateField(null=True, blank=True)
    # keeping it between 1-5
    rating = models.FloatField(
        null=True,
        blank=True,
        validators=[MaxValueValidator(5),
                    MinValueValidator(1)])
    # dropdown with two choices
    read_mode = models.CharField(max_length=20,
                                 null=True,
                                 blank=True,
                                 choices=(('HardCopy', 'Hard Copy'),
                                          ('ebook-PDF', 'eBook-PDF'),
                                          ('ebook-Kindle', 'eBook-Kindle')))
    time_taken = models.FloatField(null=True, blank=True)

    def __str__(self):
        return self.name

    # this is to tell django how to find the url to any specific instance of the Book
    def get_absolute_url(self):
        # this allows us to redirect to book detail page after adding a new book (new instance)
        return reverse('books_app-detail', kwargs={'pk': self.pk})
Пример #15
0
class EnumType(CreatedUpdatedMixin):

    ENUMTYPE_STATUS_DEPRECATED = 0
    ENUMTYPE_STATUS_PROPOSED = 1
    ENUMTYPE_STATUS_DRAFT = 3
    ENUMTYPE_STATUS_APPROVED = 6

    ENUMTYPE_STATUS = (
        (ENUMTYPE_STATUS_DEPRECATED, "Deprecated"),
        (ENUMTYPE_STATUS_PROPOSED, "Proposed"),
        (ENUMTYPE_STATUS_DRAFT, "Draft"),
        (ENUMTYPE_STATUS_APPROVED, "Approved"),
    )
    #NOTE: you cannot have ref as the primary key without breaking treebeard
    ref = models.CharField(max_length=20, primary_key=True)
    parent = models.ForeignKey("self",
                               blank=True,
                               null=True,
                               on_delete=models.CASCADE)
    name = models.CharField(max_length=60, unique=True)
    status = models.PositiveSmallIntegerField(default=1,
                                              choices=ENUMTYPE_STATUS)
    notes = MarkupField(markup_type='markdown', blank=True, null=True)

    node_order_by = ['name']

    def __str__(self):
        return self.ref

    class Meta:
        verbose_name = _("Enum Grouping")

    def save(self, *args, **kwargs):

        super().save(*args, **kwargs)
Пример #16
0
class EnumDisplay(CreatedUpdatedMixin):
    '''
    "language": "en",
        "culture": "en-US",
        "display": "SKEnumTypes",
        "abbreviation": "",
        "symbol": "" }]
    '''

    enum = models.ForeignKey(Enum, on_delete=models.CASCADE)
    # language MUST be provided and can be derived from culture
    language = models.ForeignKey(Language, on_delete=models.CASCADE)
    # culture is optional - or should it be required with a default per language
    culture = models.ForeignKey(CultureCode,
                                blank=True,
                                null=True,
                                on_delete=models.CASCADE)
    display = models.CharField(max_length=100)
    abbreviation = models.CharField(max_length=10, blank=True, null=True)
    symbol = models.CharField(max_length=10, blank=True, null=True)
    notes = MarkupField(markup_type='markdown', blank=True, null=True)

    def __str__(self):
        return self.display

    class Meta:
        verbose_name = _("Enum Output/Display")

    def save(self, *args, **kwargs):

        # language can be derived from culture
        if self.culture and not self.language:
            self.language = self.culture[0:1]

        super().save(*args, **kwargs)
Пример #17
0
class Note(models.Model):
    """
    Note is similar to an evernote note. It has a title, tags, etc.
    """
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created = models.DateTimeField(auto_now_add=True, null=True)
    updated = models.DateTimeField(auto_now=True, null=True)
    creator = models.ForeignKey(settings.AUTH_USER_MODEL, null=True)
    title = models.CharField(max_length=60)
    note = MarkupField(null=True, blank=True, markup_type='markdown')
    cases = models.ManyToManyField(Case, related_name='related_note_set', blank=True)
    editors = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='notes_user_can_edit',
        blank=True
    )
    viewers = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='notes_user_can_view',
        help_text='Who do you want to be able to view the note?',
        blank=True
    )
    notebook = models.ForeignKey(
        Notebook,
        null=True,
        blank=True
    )

    def __str__(self):
        return str(self.title)

    def get_absolute_url(self):
        return reverse('file_manager:note_detail', kwargs={'pk': self.pk})
Пример #18
0
class News(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(unique=True)
    content = MarkupField(markup_type='restructuredtext')
    publish_date = models.DateTimeField(default=datetime.datetime.now)
    image = models.ImageField(upload_to='news', null=True, blank=True)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             null=True,
                             on_delete=models.SET_NULL)

    # pylint: disable=W0232, R0903
    class Meta:
        ordering = ['-publish_date']
        verbose_name_plural = "news"
        db_table = 'news'

    def __str__(self):
        return self.title

    # pylint: disable=E0202
    def get_absolute_url(self):
        return reverse('news_details', kwargs={'slug': self.slug}) + "#article"

    def save(self,
             force_insert=False,
             force_update=False,
             using=False,
             update_fields=False):
        self.slug = slugify(self.title)
        return super(News, self).save(force_insert=force_insert,
                                      force_update=force_insert,
                                      using=using,
                                      update_fields=update_fields)
Пример #19
0
class Post(models.Model):
    title = models.CharField(max_length=200)
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    body = MarkupField(markup_type='markdown')

    def __str__(self):
        return self.title
Пример #20
0
class Snippet(models.Model):
    title = models.CharField(max_length=128, unique=True)
    description = models.CharField(max_length=200, default="")
    body = MarkupField(default="", default_markup_type='markdown')

    def __unicode__(self):
        return "Snippet '%s'" % (self.title, )
Пример #21
0
class Article(behaviours.Permalinkable, behaviours.Authorable,
              behaviours.Publishable, TimeStampedModel):

    title = models.CharField(_('Title'), max_length=100)

    category = models.ForeignKey(Category, related_name='articles')

    content = MarkupField(_('Content'), default_markup_type='markdown')

    hits = models.PositiveIntegerField(_('Hits'), default=0)

    objects = ArticleManager()
    votes = Votes()
    tags = TaggableManager(blank=True)

    class Meta:
        app_label = 'kb'
        verbose_name = _('Article')
        verbose_name_plural = _('Articles')

    def __str__(self):
        return self.title

    def related(self, num=5):
        qs = Article.objects.published()
        qs = qs.filter(tags__in=self.tags.all())
        qs = qs.exclude(pk=self.pk)
        return qs[:num]

    def increase_hits(self):
        Article.objects.filter(pk=self.pk).update(hits=F('hits') + 1)
Пример #22
0
class Download(TimeStampedModel):
    title = models.CharField(max_length=128)
    body = MarkupField(markup_type="restructuredtext")
    active = models.BooleanField(default=True, verbose_name=_("Active"))
    top = models.BooleanField(default=False, verbose_name=_("Top-Download"))
    file = models.FileField(upload_to="uploads/")
    icon = models.TextField(default="file-o")

    class Meta:
        verbose_name = _("Download")
        verbose_name_plural = _("Downloads")

    def __str__(self):
        return self.title

    @staticmethod
    @receiver(models.signals.pre_save, sender="LZK.Download")
    def pre_save(sender, instance, raw, **kwargs):
        icons = {
            ("audio", ): "file-audio-o",
            ("image", ): "file-image-o",
            ("video", ): "file-video-o",
            ("text", ): "file-text-o",
            ("application", "pdf"): "file-pdf-o",
            ("application", "zip"): "file-archive-o",
        }
        instance.file.seek(0)
        mimetype = magic.from_buffer(instance.file.read(2048), mime=True)
        instance.file.seek(0)
        maintype, subtype, _ = mimeparse.parse_mime_type(mimetype)
        instance.icon = icons.get((maintype, subtype),
                                  icons.get((maintype, ), "file-o"))
Пример #23
0
class State(models.Model):
    """
    States, used for configuration.
    """

    abbreviation = models.CharField(max_length=2, primary_key=True)
    name = models.CharField(max_length=100)
    census_geoid = models.CharField(max_length=2, unique=True)

    status_text = MarkupField(markup_type="markdown", default="")
    status = models.CharField(
        max_length=30,
        default=StateStatus.NEED_TO_COLLECT.value,
        choices=((c.value, c.value) for c in StateStatus),
    )

    show_crowdsourcing_tools = models.BooleanField(default=False)

    def display_status(self):
        return {
            StateStatus.NEED_TO_COLLECT.value: "Need to Collect Data",
            StateStatus.GEOGRAPHY.value: "Geography Collected",
            StateStatus.ELECTION_DATA_LINKED.value: "Election Data Linked",
            StateStatus.CENSUS_DATA_LINKED.value: "Census Data Linked",
            StateStatus.VALIDATED.value: "Validated",
        }[self.status]

    def __str__(self):
        return self.name

    class Meta:
        ordering = ["name"]
Пример #24
0
class Addon(UUIDPrimaryKeyMixin, models.Model):
    namespace = models.ForeignKey("namespace.Namespace", related_name="addons")
    identifier = models.CharField(max_length=255)
    description = MarkupField(help_text="in markdown")

    def __str__(self):
        return f"{self.namespace}/{self.identifier}"
Пример #25
0
class Answer(models.Model):
    user = models.ForeignKey(User,
                             blank=False,
                             null=False,
                             verbose_name=_("Usuario"))
    question = models.ForeignKey(Question,
                                 blank=False,
                                 null=False,
                                 verbose_name=_("Pregunta"))
    date = models.DateTimeField(blank=False,
                                null=False,
                                verbose_name=_('Fecha'),
                                auto_now=True)
    description = MarkupField(default_markup_type="markdown",
                              blank=False,
                              null=False,
                              verbose_name=_('Descripcion'))
    flag = models.BooleanField(blank=False, null=False, default=False)

    class Meta:
        verbose_name = _("Respuesta")
        verbose_name_plural = _('Respuestas')

    def __unicode__(self):
        return self.question.title
Пример #26
0
class DDLEvent(TimeStampedModel):
    """
    Defines fields that all DDL events share no matter their event type.
    """

    name = models.CharField(max_length=255)
    slug = AutoSlugField(populate_from='name', unique=True)
    begins = models.DateTimeField(**nullable)
    finishes = models.DateTimeField(**nullable)
    details = MarkupField(markup_type='markdown',
                          help_text='Edit in Markdown',
                          **nullable)

    class Meta:
        abstract = True

    def duration(self, humanize=False):
        """
        Returns the duration of the event, either in seconds or as a humanized
        time stamp (e.g. the number of days, hours, etc.).
        """
        seconds = (self.finishes - self.begins).total_seconds()
        if humanize:
            return humanizedelta(seconds=seconds)
        return seconds

    def get_absolute_url(self):
        """
        Return the detail view of the event object.
        """
        raise NotImplementedError("DDL Events shoud have a page view!")

    def __unicode__(self):
        return self.name
Пример #27
0
class Page(ContentManageable):
    title = models.CharField(max_length=500)
    keywords = models.CharField(max_length=1000, blank=True, help_text="HTTP meta-keywords")
    description = models.TextField(blank=True, help_text="HTTP meta-description")
    path = models.CharField(max_length=500, validators=[is_valid_page_path], unique=True, db_index=True)
    content = MarkupField(default_markup_type=DEFAULT_MARKUP_TYPE)
    is_published = models.BooleanField(default=True, db_index=True)
    template_name = models.CharField(max_length=100, blank=True,
        help_text="Example: 'pages/about.html'. If this isn't provided, the system will use 'pages/default.html'.")

    objects = PageManager()

    class Meta(object):
        ordering = ['title', 'path']

    def clean(self):
        # Strip leading and trailing slashes off self.path.
        self.path = self.path.strip('/')

    def get_title(self):
        if self.title:
            return self.title
        else:
            return '** No Title **'

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return "/{0}/".format(self.path)
Пример #28
0
class Minutes(ContentManageable):
    date = models.DateField(verbose_name='Meeting Date', db_index=True)
    content = MarkupField(default_markup_type=DEFAULT_MARKUP_TYPE)
    is_published = models.BooleanField(default=False, db_index=True)

    objects = MinutesManager()

    class Meta:
        verbose_name = 'minutes'
        verbose_name_plural = 'minutes'

    def __str__(self):
        return "PSF Meeting Minutes %s" % self.date.strftime("%B %d, %Y")

    def get_absolute_url(self):
        return reverse('minutes_detail', kwargs={
            'year': self.get_date_year(),
            'month': self.get_date_month(),
            'day': self.get_date_day(),
        })

    # Helper methods for sitetree
    def get_date_year(self):
        return self.date.strftime("%Y")

    def get_date_month(self):
        return self.date.strftime("%m").zfill(2)

    def get_date_day(self):
        return self.date.strftime("%d").zfill(2)
Пример #29
0
class Project(models.Model):
    slug = models.SlugField(
        'unique identifier for project',
        max_length=50,
        unique=True,
        help_text="(this will become part of your projects URL)")
    name = models.CharField('displayed name of project', max_length=100)
    description = MarkupField(default_markup_type='markdown', escape_html=True)
    official = models.BooleanField(default=False)
    creation_date = models.DateTimeField(auto_now_add=True)
    update_date = models.DateTimeField(auto_now=True)
    tags = TagField('Tags')

    lead = models.ForeignKey(User, related_name='projects_lead_on')
    members = models.ManyToManyField(User, through='Role')

    subscriptions = generic.GenericRelation(Subscription)

    def __unicode__(self):
        return self.name

    def get_absolute_url(self):
        return reverse('project_detail', args=[self.slug])

    def get_members(self):
        return self.members.filter(project_roles__status='A')
Пример #30
0
class User(AbstractUser):
    bio = MarkupField(blank=True, default_markup_type=DEFAULT_MARKUP_TYPE)

    SEARCH_PRIVATE = 0
    SEARCH_PUBLIC = 1
    SEARCH_CHOICES = (
        (SEARCH_PUBLIC,
         'Allow search engines to index my profile page (recommended)'),
        (SEARCH_PRIVATE,
         "Don't allow search engines to index my profile page"),
    )
    search_visibility = models.IntegerField(choices=SEARCH_CHOICES,
                                            default=SEARCH_PUBLIC)

    EMAIL_PUBLIC = 0
    EMAIL_PRIVATE = 1
    EMAIL_NEVER = 2
    EMAIL_CHOICES = (
        (EMAIL_PUBLIC, 'Anyone can see my e-mail address'),
        (EMAIL_PRIVATE, 'Only logged-in users can see my e-mail address'),
        (EMAIL_NEVER, 'No one can ever see my e-mail address'),
    )
    email_privacy = models.IntegerField('E-mail privacy',
                                        choices=EMAIL_CHOICES,
                                        default=EMAIL_NEVER)

    objects = UserManager()

    def get_absolute_url(self):
        return reverse('users:user_detail', kwargs={'slug': self.username})