denormalize models, added signals

This commit is contained in:
slav0nic 2009-05-24 18:50:57 +03:00
parent c5a14d4cf0
commit 2dfcc591c0
7 changed files with 68 additions and 59 deletions

View file

@ -14,4 +14,5 @@ djapian_db
*.kpf
*.autosave
static/forum/avatars
secret.txt
secret.txt
django_evolution

View file

@ -0,0 +1 @@
import signals

View file

@ -92,6 +92,8 @@ class Forum(models.Model):
moderators = models.ManyToManyField(User, blank=True, null=True, verbose_name=_('Moderators'))
updated = models.DateTimeField(_('Updated'), default=datetime.now)
post_count = models.IntegerField(_('Post count'), blank=True, default=0)
topic_count = models.IntegerField(_('Topic count'), blank=True, default=0)
last_post = models.ForeignKey('Post', related_name='last_post', blank=True, null=True)
class Meta:
ordering = ['position']
@ -101,23 +103,13 @@ class Forum(models.Model):
def __unicode__(self):
return self.name
def topic_count(self):
return self.topics.all().count()
def get_absolute_url(self):
return reverse('forum', args=[self.id])
@property
def posts(self):
return Post.objects.filter(topic__forum=self).select_related()
@property
def last_post(self):
posts = self.posts.order_by('-created').select_related()
try:
return posts[0]
except IndexError:
return None
class Topic(models.Model):
forum = models.ForeignKey(Forum, related_name='topics', verbose_name=_('Forum'))
@ -130,6 +122,7 @@ class Topic(models.Model):
closed = models.BooleanField(_('Closed'), blank=True, default=False)
subscribers = models.ManyToManyField(User, related_name='subscriptions', verbose_name=_('Subscribers'), blank=True)
post_count = models.IntegerField(_('Post count'), blank=True, default=0)
last_post = models.ForeignKey('Post', related_name='last_topic_post', blank=True, null=True)
class Meta:
ordering = ['-updated']
@ -144,9 +137,6 @@ class Topic(models.Model):
return self.posts.all().order_by('created').select_related()[0]
@property
def last_post(self):
return self.posts.all().order_by('-created').select_related()[0]
def reply_count(self):
return self.post_count - 1
@ -210,19 +200,7 @@ class Post(models.Model):
self.body_text = strip_tags(self.body_html)
self.body_html = urlize(self.body_html)
self.body_html = smiles(self.body_html)
new = self.id is None
if new:
#new post created
super(Post, self).save(*args, **kwargs)
self.topic.updated = datetime.now()
self.topic.post_count = Post.objects.filter(topic=self.topic).count()
self.topic.save()
self.topic.forum.updated = self.topic.updated
self.topic.forum.post_count = Post.objects.filter(topic__forum=self.topic.forum).count()
self.topic.forum.save()
else:
#edit post
super(Post, self).save(*args, **kwargs)
super(Post, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('post', args=[self.id])
@ -231,10 +209,6 @@ class Post(models.Model):
self_id = self.id
head_post_id = self.topic.posts.order_by('created')[0].id
super(Post, self).delete(*args, **kwargs)
self.topic.post_count = Post.objects.filter(topic=self.topic).count()
self.topic.save()
self.topic.forum.post_count = Post.objects.filter(topic__forum=self.topic.forum).count()
self.topic.forum.save()
if self_id == head_post_id:
self.topic.delete()

View file

@ -1,11 +1,43 @@
from datetime import datetime
from django.db.models.signals import post_save, pre_save, post_delete
from forum.subscription import notify_topic_subscribers, notify_pm_recipients
from forum.models import Post, PrivateMessage
from forum.models import Topic, Post, PrivateMessage
def post_saved(instance, **kwargs):
notify_topic_subscribers(instance)
created = kwargs.get('created')
post = instance
if created:
updated_time = datetime.now()
post.topic.updated = updated_time
post.topic.post_count = Post.objects.filter(topic=post.topic).count()
post.topic.save(force_update=True)
post.topic.forum.updated = updated_time
post.topic.forum.post_count = Post.objects.filter(topic__forum=post.topic.forum).count()
post.topic.forum.last_post = post
post.topic.forum.save(force_update=True)
notify_topic_subscribers(post)
def post_deleted(instance, **kwargs):
post = instance
post.topic.post_count = Post.objects.filter(topic=post.topic).count()
post.topic.save()
post.topic.forum.post_count = Post.objects.filter(topic__forum=post.topic.forum).count()
post.topic.forum.save()
def pm_saved(instance, **kwargs):
notify_pm_recipients(instance)
def topic_saved(instance, **kwargs):
created = kwargs.get('created')
topic = instance
if created:
topic.forum.topic_count = topic.forum.topics.count()
topic.forum.save(force_update=True)
post_save.connect(post_saved, sender=Post)
post_save.connect(pm_saved, sender=PrivateMessage)
post_save.connect(pm_saved, sender=PrivateMessage)
post_save.connect(topic_saved, sender=Topic)
post_delete.connect(post_deleted, sender=Post)

View file

@ -2,9 +2,9 @@
{% load i18n %}
{% if forum.last_post.topic %}
<tr {% if forum.last_post.topic|has_unreads:user %}class="inew"{% endif %}>
<tr {% if forum.last_post.topic|has_unreads:user %}class="inew"{% endif %}>
{% else %}
<tr>
<tr>
{% endif %}
<td class="tcl">
<div class="intd">
@ -29,8 +29,8 @@
<td class="tcr">
{% if forum.updated %}
{% if forum.last_post.topic %}
<a href="{{ forum.last_post.get_absolute_url }}">{% forum_time forum.last_post.created %}</a>
<span class="byuser">{% trans "by" %} {{ forum.last_post.user }}</span>
<a href="{{ forum.last_post.get_absolute_url }}">{% forum_time forum.last_post.created %}</a>
<span class="byuser">{% trans "by" %} {{ forum.last_post.user }}</span>
{% endif %}
{% endif %}
</td>

View file

@ -4,28 +4,28 @@
{% block content %}
<div id="idx1" class="blocktable">
{% for iter in cats %}
<h2>
<a href="{% url forum_feed "category" %}{{ iter.cat.id }}/"><img src="{{ MEDIA_URL }}/forum/img/feed-icon-small.png" alt="[RSS Feed]" title="[RSS Feed]" class="rss" /></a>
<span>{{ iter.cat }}</span>
{% for iter in cats %}
<h2>
<a href="{% url forum_feed "category" %}{{ iter.cat.id }}/"><img src="{{ MEDIA_URL }}/forum/img/feed-icon-small.png" alt="[RSS Feed]" title="[RSS Feed]" class="rss" /></a>
<span>{{ iter.cat }}</span>
</h2>
<div class="box">
<div class="inbox">
<table cellspacing="0">
<thead>
<tr>
<th class="tcl" scope="col">{% trans "Forum" %}</th>
<th class="tc2" scope="col">{% trans "Topics" %}</th>
<th class="tc3" scope="col">{% trans "Posts" %}</th>
<th class="tcr" scope="col">{% trans "Last post" %}</th>
</tr>
</thead>
<tbody>
{% for forum in iter.forums %}
{% include 'forum/forum_row.html' %}
{% endfor %}
</tbody>
</table>
<thead>
<tr>
<th class="tcl" scope="col">{% trans "Forum" %}</th>
<th class="tc2" scope="col">{% trans "Topics" %}</th>
<th class="tc3" scope="col">{% trans "Posts" %}</th>
<th class="tcr" scope="col">{% trans "Last post" %}</th>
</tr>
</thead>
<tbody>
{% for forum in iter.forums %}
{% include 'forum/forum_row.html' %}
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endfor %}

View file

@ -39,7 +39,7 @@ def index(request, full=True):
user_groups = request.user.groups.all()
if request.user.is_anonymous(): # in django 1.1 EmptyQuerySet raise exception
user_groups = []
for forum in Forum.objects.filter(Q(category__groups__in=user_groups) | Q(category__groups__isnull=True)).select_related():
for forum in Forum.objects.filter(Q(category__groups__in=user_groups) | Q(category__groups__isnull=True)).select_related('category'):
cat = cats.setdefault(forum.category.id,
{'cat': forum.category, 'forums': []})
cat['forums'].append(forum)
@ -47,6 +47,7 @@ def index(request, full=True):
cmpdef = lambda a, b: cmp(a['cat'].position, b['cat'].position)
cats = sorted(cats.values(), cmpdef)
if full:
return {'cats': cats,
'posts': Post.objects.count(),