agdj/blog/models.py
author Adam Gomaa <code@adam.gomaa.us>
Sun Feb 01 01:35:02 2009 -0500
changeset 416 5a586a8c2f8f
parent 388 2c8b20b9e628
child 451 88b49087ec1a
permissions -rw-r--r--
Switch to date-based URLs everywhere except the feed URLs of old posts, so I don't spam everyone's feedreader.
code@14
     1
from django.db import models
code@14
     2
code@101
     3
import tagging
code@101
     4
from tagging.fields import TagField
code@88
     5
code@266
     6
from agdj.blog.managers import PublicManager
code@416
     7
from agdj.utils import cached_property, dictproperty
code@88
     8
code@263
     9
code@329
    10
class Entry(models.Model):
code@267
    11
    "A blog entry"
code@267
    12
code@119
    13
    id = models.AutoField(primary_key=True)
code@120
    14
    title = models.CharField(max_length=64)
code@88
    15
    source = models.TextField()
code@88
    16
    description = models.TextField()
code@89
    17
    pub_date = models.DateTimeField(auto_now_add=True)
code@120
    18
    slug = models.CharField(max_length=64, unique=True)
code@88
    19
    public = models.BooleanField()
code@416
    20
    SLUG_ONLY = "slug-only"
code@416
    21
    DATE_BASED = "date-based"
code@416
    22
    URL_SCHEME_CHOICES = (
code@416
    23
        (SLUG_ONLY, "Slug Only"),
code@416
    24
        (DATE_BASED, "Date-based"),
code@416
    25
        )
code@416
    26
    feed_url_scheme = models.CharField(
code@416
    27
        max_length=64, choices=URL_SCHEME_CHOICES,
code@416
    28
        help_text="Does this post use the new date-based URL or the old "
code@416
    29
        "slug-based one in feed URLs and GUIDs?",
code@416
    30
        default=DATE_BASED)
code@266
    31
code@266
    32
    # This is a hack that even I don't understand
code@101
    33
    text_tags = TagField(db_column="tags")
code@266
    34
code@332
    35
    objects = models.Manager()
code@334
    36
    public_objects = PublicManager()
code@332
    37
code@88
    38
    class Meta:
code@88
    39
        db_table = u'agus_blog_entry'
code@388
    40
        ordering = ("-pub_date",)
code@272
    41
        verbose_name_plural = u'Entries'
code@96
    42
code@263
    43
    def __unicode__(self):
code@263
    44
        return self.title
code@263
    45
code@342
    46
    def save(self, *args, **kwargs):
code@342
    47
        from django.core.cache import cache
code@342
    48
code@342
    49
        # If this is an update, then clear the cache keys.
code@342
    50
        if self.pk:
code@342
    51
            cache_key = "%s.%s.%s(%s)" % (self.__class__.__module__,
code@342
    52
                                          self.__class__.__name__,
code@342
    53
                                          "rendered",
code@342
    54
                                          self.pk)
code@342
    55
            cache.delete(cache_key)
code@342
    56
code@342
    57
        return super(Entry, self).save(*args, **kwargs)
code@342
    58
code@416
    59
    @dictproperty
code@416
    60
    def urls(self, name):
code@416
    61
        from django.core.urlresolvers import reverse
code@416
    62
code@416
    63
        if name == "feed_url":
code@416
    64
            if self.feed_url_scheme == self.DATE_BASED:
code@416
    65
                return self.urls.view
code@416
    66
            else:
code@416
    67
                return reverse("redirect-to-date-url", args=[self.slug])
code@416
    68
        elif name == "view":
code@416
    69
                return reverse("view-blog-post",
code@416
    70
                               args=[self.pub_date.year,
code@416
    71
                                     self.pub_date.strftime("%b").lower(),
code@416
    72
                                     self.pub_date.day,
code@416
    73
                                     self.slug])
code@416
    74
code@416
    75
code@342
    76
code@342
    77
    @cached_property
code@88
    78
    def rendered(self):
code@230
    79
        from agdj.markup import markdown
code@89
    80
        return markdown(self.source)
code@263
    81
code@89
    82
    @property
code@89
    83
    def public_comments(self):
code@89
    84
        return self.comments.filter(public=True)
code@89
    85
code@359
    86
    @property
code@359
    87
    def spam_count(self):
code@361
    88
        return Comment.with_unpublished.filter(
code@361
    89
            public=False, entry=self).count()
code@359
    90
code@342
    91
code@89
    92
tagging.register(Entry)
code@169
    93
code@88
    94
code@329
    95
class Comment(models.Model):
code@267
    96
    "A comment on a blog entry"
code@267
    97
code@119
    98
    id = models.AutoField(primary_key=True)
code@386
    99
    ip = models.TextField(blank=True)
code@121
   100
    name = models.CharField(max_length=64, blank=True)
code@121
   101
    url = models.CharField(max_length=128, blank=True)
code@96
   102
    public = models.BooleanField(default=False)
code@89
   103
    entry = models.ForeignKey(Entry, related_name="comments", db_column="agus_blog_entry_entry_id")
code@89
   104
    pub_date = models.DateTimeField(auto_now_add=True)
code@121
   105
    text = models.TextField(blank=True)
code@266
   106
code@264
   107
    # This should be the _default_manager
code@194
   108
    objects = PublicManager()
code@361
   109
    with_unpublished = models.Manager()
code@264
   110
code@88
   111
    class Meta:
code@88
   112
        db_table = u'agus_blog_comment'
code@329
   113
        ordering = ("-pub_date",)
code@266
   114
code@266
   115
    def __unicode__(self):
code@266
   116
        return u"Comment %d on '%s'" % (self.id, self.entry)
code@266
   117
code@89
   118
    @property
code@89
   119
    def rendered(self):
code@230
   120
        from agdj.markup import markdown_untrusted
code@89
   121
        return markdown_untrusted(self.text)
code@92
   122
code@336
   123
    def save(self, *args, **kwargs):
code@266
   124
        # I'm not sure why - maybe because the database was originally
code@266
   125
        # created by SQLAlchemy and not syncdb - but the AutoField
code@266
   126
        # doesn't really work.
code@114
   127
        if self.id is None:
code@114
   128
            from django.db import connection
code@114
   129
            cursor = connection.cursor()
code@114
   130
            cursor.execute("select nextval('agus_blog_comment_id_seq');")
code@114
   131
            self.id = cursor.fetchone()[0]
code@336
   132
        super(self.__class__, self).save(*args, **kwargs)
code@92
   133