##// END OF EJS Templates
Added replies manytomany field to the post to get its replies more efficiently.
neko259 -
r169:4857f106 default
parent child Browse files
Show More
@@ -0,0 +1,81 b''
1 # -*- coding: utf-8 -*-
2 import datetime
3 from south.db import db
4 from south.v2 import SchemaMigration
5 from django.db import models
6 from boards.models import Post, NO_PARENT
7
8
9 class Migration(SchemaMigration):
10
11 def forwards(self, orm):
12 # Adding M2M table for field replies on 'Post'
13 m2m_table_name = db.shorten_name(u'boards_post_replies')
14 db.create_table(m2m_table_name, (
15 ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
16 ('from_post', models.ForeignKey(orm[u'boards.post'], null=False)),
17 ('to_post', models.ForeignKey(orm[u'boards.post'], null=False))
18 ))
19 db.create_unique(m2m_table_name, ['from_post_id', 'to_post_id'])
20
21 for post in Post.objects.all():
22 if post.parent != NO_PARENT:
23 parent = Post.objects.get(id=post.parent)
24 parent.replies.add(post)
25
26
27 def backwards(self, orm):
28 # Removing M2M table for field replies on 'Post'
29 db.delete_table(db.shorten_name(u'boards_post_replies'))
30
31
32 models = {
33 u'boards.ban': {
34 'Meta': {'object_name': 'Ban'},
35 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
36 'ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'})
37 },
38 u'boards.post': {
39 'Meta': {'object_name': 'Post'},
40 '_text_rendered': ('django.db.models.fields.TextField', [], {}),
41 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
42 'image': ('boards.thumbs.ImageWithThumbsField', [], {'max_length': '100', 'blank': 'True'}),
43 'image_height': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
44 'image_width': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
45 'last_edit_time': ('django.db.models.fields.DateTimeField', [], {}),
46 'parent': ('django.db.models.fields.BigIntegerField', [], {}),
47 'poster_ip': ('django.db.models.fields.GenericIPAddressField', [], {'max_length': '39'}),
48 'poster_user_agent': ('django.db.models.fields.TextField', [], {}),
49 'pub_time': ('django.db.models.fields.DateTimeField', [], {}),
50 'replies': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'re+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}),
51 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['boards.Tag']", 'symmetrical': 'False'}),
52 'text': ('markupfield.fields.MarkupField', [], {'rendered_field': 'True'}),
53 'text_markup_type': ('django.db.models.fields.CharField', [], {'default': "'markdown'", 'max_length': '30'}),
54 'title': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
55 'user': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'to': u"orm['boards.User']", 'null': 'True'})
56 },
57 u'boards.setting': {
58 'Meta': {'object_name': 'Setting'},
59 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
60 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
61 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['boards.User']"}),
62 'value': ('django.db.models.fields.CharField', [], {'max_length': '50'})
63 },
64 u'boards.tag': {
65 'Meta': {'object_name': 'Tag'},
66 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
67 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
68 },
69 u'boards.user': {
70 'Meta': {'object_name': 'User'},
71 'fav_tags': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': u"orm['boards.Tag']", 'null': 'True', 'blank': 'True'}),
72 'fav_threads': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'symmetrical': 'False', 'to': u"orm['boards.Post']"}),
73 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
74 'last_access_time': ('django.db.models.fields.DateTimeField', [], {}),
75 'rank': ('django.db.models.fields.IntegerField', [], {}),
76 'registration_time': ('django.db.models.fields.DateTimeField', [], {}),
77 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '50'})
78 }
79 }
80
81 complete_apps = ['boards'] No newline at end of file
@@ -5,10 +5,10 b' import time'
5 5 import math
6 6
7 7 from django.db import models
8 from django.db.models import Count
8 9 from django.http import Http404
9 10 from django.utils import timezone
10 11 from markupfield.fields import MarkupField
11 from threading import Thread
12 12
13 13 from neboard import settings
14 14 import thumbs
@@ -45,6 +45,10 b' class PostManager(models.Manager):'
45 45 last_edit_time=timezone.now(),
46 46 user=user)
47 47
48 if parent_id != NO_PARENT:
49 parent = self.get(id=parent_id)
50 parent.replies.add(post)
51
48 52 if tags:
49 53 map(post.tags.add, tags)
50 54
@@ -56,9 +60,8 b' class PostManager(models.Manager):'
56 60 return post
57 61
58 62 def delete_post(self, post):
59 children = self.filter(parent=post.id)
60
61 map(self.delete_post, children)
63 if post.replies.count() > 0:
64 map(self.delete_post, post.replies)
62 65 post.delete()
63 66
64 67 def delete_posts_by_ip(self, ip):
@@ -93,11 +96,9 b' class PostManager(models.Manager):'
93 96 except Post.DoesNotExist:
94 97 raise Http404
95 98
96 if opening_post.parent == NO_PARENT:
97 replies = self.filter(parent=opening_post_id)
98
99 if opening_post.replies:
99 100 thread = [opening_post]
100 thread.extend(replies)
101 thread.extend(opening_post.replies.all())
101 102
102 103 return thread
103 104
@@ -222,11 +223,17 b' class Post(models.Model):'
222 223
223 224 poster_ip = models.GenericIPAddressField()
224 225 poster_user_agent = models.TextField()
226
227 # TODO Convert this field to ForeignKey
225 228 parent = models.BigIntegerField()
229
226 230 tags = models.ManyToManyField(Tag)
227 231 last_edit_time = models.DateTimeField()
228 232 user = models.ForeignKey('User', null=True, default=None)
229 233
234 replies = models.ManyToManyField('Post', symmetrical=False, null=True,
235 blank=True, related_name='re+')
236
230 237 def __unicode__(self):
231 238 return '#' + str(self.id) + ' ' + self.title + ' (' + \
232 239 self.text.raw[:50] + ')'
@@ -239,16 +246,15 b' class Post(models.Model):'
239 246 return title
240 247
241 248 def _get_replies(self):
242 return Post.objects.filter(parent=self.id)
249 return self.replies
243 250
244 251 def get_reply_count(self):
245 return self._get_replies().count()
252 return self.replies.count()
246 253
247 254 def get_images_count(self):
248 255 images_count = 1 if self.image else 0
249 256
250 replies = self._get_replies()
251 for reply in replies:
257 for reply in self.replies:
252 258 if reply.image:
253 259 images_count += 1
254 260
@@ -257,9 +263,9 b' class Post(models.Model):'
257 263 def can_bump(self):
258 264 """Check if the thread can be bumped by replying"""
259 265
260 replies_count = self.get_reply_count() + 1
266 post_count = self.get_reply_count() + 1
261 267
262 return replies_count <= settings.MAX_POSTS_PER_THREAD
268 return post_count <= settings.MAX_POSTS_PER_THREAD
263 269
264 270 def get_last_replies(self):
265 271 if settings.LAST_REPLIES_COUNT > 0:
@@ -268,8 +274,8 b' class Post(models.Model):'
268 274 if reply_count > 0:
269 275 reply_count_to_show = min(settings.LAST_REPLIES_COUNT,
270 276 reply_count)
271 last_replies = self._get_replies()[reply_count
272 - reply_count_to_show:]
277 last_replies = self.replies.all()[reply_count -
278 reply_count_to_show:]
273 279
274 280 return last_replies
275 281
@@ -219,6 +219,7 b' def jump_to_post(request, post_id):'
219 219 if boards.models.NO_PARENT == post.parent:
220 220 return redirect(thread, post_id=post.id)
221 221 else:
222 # TODO Change this code to not use 'parent' field anymore
222 223 parent_thread = get_object_or_404(Post, id=post.parent)
223 224 return redirect(reverse(thread, kwargs={'post_id': parent_thread.id})
224 225 + '#' + str(post.id))
General Comments 0
You need to be logged in to leave comments. Login now