comparison gpp/forums/models.py @ 75:374b24dd2f9a

First checkin of forums. Have noticed cascading delete behavior. Will try to prevent this next.
author Brian Neal <bgneal@gmail.com>
date Sun, 05 Jul 2009 00:03:40 +0000
parents
children e356ea79a7a2
comparison
equal deleted inserted replaced
74:df56795771a6 75:374b24dd2f9a
1 """
2 Models for the forums application.
3 """
4 from django.db import models
5 from django.contrib.auth.models import User, Group
6 from django.template.loader import render_to_string
7
8
9 class Category(models.Model):
10 name = models.CharField(max_length=80)
11 slug = models.SlugField(max_length=80)
12 position = models.IntegerField(blank=True, default=0)
13 groups = models.ManyToManyField(Group, blank=True, null=True,
14 help_text="If groups are assigned to this category, only members" \
15 " of those groups can view this category.")
16
17 class Meta:
18 ordering = ('position', )
19 verbose_name_plural = 'Categories'
20
21 def __unicode__(self):
22 return self.name
23
24
25 class Forum(models.Model):
26 category = models.ForeignKey(Category, related_name='forums')
27 name = models.CharField(max_length=80)
28 slug = models.SlugField(max_length=80)
29 description = models.TextField(blank=True, default='')
30 position = models.IntegerField(blank=True, default=0)
31 moderators = models.ManyToManyField(Group, blank=True, null=True)
32
33 # denormalized fields to reduce database hits
34 topic_count = models.IntegerField(blank=True, default=0)
35 post_count = models.IntegerField(blank=True, default=0)
36 last_post = models.OneToOneField('Post', blank=True, null=True,
37 related_name='parent_forum')
38
39 class Meta:
40 ordering = ('position', )
41
42 def __unicode__(self):
43 return self.name
44
45 def topic_count_update(self):
46 """Call to notify the forum that its topic count has been updated."""
47 self.topic_count = Topic.objects.filter(forum=self).count()
48
49 def post_count_update(self):
50 """Call to notify the forum that its post count has been updated."""
51 my_posts = Post.objects.filter(topic__forum=self)
52 self.post_count = my_posts.count()
53 if self.post_count > 0:
54 self.last_post = my_posts[self.post_count - 1]
55 else:
56 self.last_post = None
57
58
59 class Topic(models.Model):
60 forum = models.ForeignKey(Forum, related_name='topics')
61 name = models.CharField(max_length=255)
62 creation_date = models.DateTimeField(auto_now_add=True)
63 user = models.ForeignKey(User)
64 view_count = models.IntegerField(blank=True, default=0)
65 sticky = models.BooleanField(blank=True, default=False)
66 locked = models.BooleanField(blank=True, default=False)
67
68 # denormalized fields to reduce database hits
69 post_count = models.IntegerField(blank=True, default=0)
70 update_date = models.DateTimeField(auto_now=True)
71 last_post = models.OneToOneField('Post', blank=True, null=True,
72 related_name='parent_topic')
73
74 class Meta:
75 ordering = ('-sticky', '-update_date', )
76
77 def __unicode__(self):
78 return self.name
79
80 def post_count_update(self):
81 """
82 Call this function to notify the topic instance that its post count
83 has changed.
84 """
85 my_posts = Post.objects.filter(topic=self)
86 self.post_count = my_posts.count()
87 if self.post_count > 0:
88 self.last_post = my_posts[self.post_count - 1]
89 self.update_date = self.last_post.creation_date
90 else:
91 self.last_post = None
92 self.update_date = self.creation_date
93
94
95 class Post(models.Model):
96 topic = models.ForeignKey(Topic, related_name='posts')
97 user = models.ForeignKey(User, related_name='posts')
98 creation_date = models.DateTimeField(auto_now_add=True)
99 update_date = models.DateTimeField(auto_now=True)
100 body = models.TextField()
101 html = models.TextField()
102 user_ip = models.IPAddressField(blank=True, default='')
103
104 class Meta:
105 ordering = ('creation_date', )
106
107 def summary(self):
108 LIMIT = 50
109 if len(self.body) < LIMIT:
110 return self.body
111 return self.body[:LIMIT] + '...'
112
113 def __unicode__(self):
114 return self.summary()
115
116 def save(self, *args, **kwargs):
117 html = render_to_string('forums/post.html', {'data': self.body})
118 self.html = html.strip()
119 super(Post, self).save(*args, **kwargs)
120
121 def delete(self, *args, **kwargs):
122 first_post_id = self.topic.posts.all()[0].id
123 super(Post, self).delete(*args, **kwargs)
124 if self.id == first_post_id:
125 self.topic.delete()
126
127 # TODO: A "read" table
128 # TODO: A flagged post table