##// 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 import math
5 import math
6
6
7 from django.db import models
7 from django.db import models
8 from django.db.models import Count
8 from django.http import Http404
9 from django.http import Http404
9 from django.utils import timezone
10 from django.utils import timezone
10 from markupfield.fields import MarkupField
11 from markupfield.fields import MarkupField
11 from threading import Thread
12
12
13 from neboard import settings
13 from neboard import settings
14 import thumbs
14 import thumbs
@@ -45,6 +45,10 b' class PostManager(models.Manager):'
45 last_edit_time=timezone.now(),
45 last_edit_time=timezone.now(),
46 user=user)
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 if tags:
52 if tags:
49 map(post.tags.add, tags)
53 map(post.tags.add, tags)
50
54
@@ -56,9 +60,8 b' class PostManager(models.Manager):'
56 return post
60 return post
57
61
58 def delete_post(self, post):
62 def delete_post(self, post):
59 children = self.filter(parent=post.id)
63 if post.replies.count() > 0:
60
64 map(self.delete_post, post.replies)
61 map(self.delete_post, children)
62 post.delete()
65 post.delete()
63
66
64 def delete_posts_by_ip(self, ip):
67 def delete_posts_by_ip(self, ip):
@@ -93,11 +96,9 b' class PostManager(models.Manager):'
93 except Post.DoesNotExist:
96 except Post.DoesNotExist:
94 raise Http404
97 raise Http404
95
98
96 if opening_post.parent == NO_PARENT:
99 if opening_post.replies:
97 replies = self.filter(parent=opening_post_id)
98
99 thread = [opening_post]
100 thread = [opening_post]
100 thread.extend(replies)
101 thread.extend(opening_post.replies.all())
101
102
102 return thread
103 return thread
103
104
@@ -222,11 +223,17 b' class Post(models.Model):'
222
223
223 poster_ip = models.GenericIPAddressField()
224 poster_ip = models.GenericIPAddressField()
224 poster_user_agent = models.TextField()
225 poster_user_agent = models.TextField()
226
227 # TODO Convert this field to ForeignKey
225 parent = models.BigIntegerField()
228 parent = models.BigIntegerField()
229
226 tags = models.ManyToManyField(Tag)
230 tags = models.ManyToManyField(Tag)
227 last_edit_time = models.DateTimeField()
231 last_edit_time = models.DateTimeField()
228 user = models.ForeignKey('User', null=True, default=None)
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 def __unicode__(self):
237 def __unicode__(self):
231 return '#' + str(self.id) + ' ' + self.title + ' (' + \
238 return '#' + str(self.id) + ' ' + self.title + ' (' + \
232 self.text.raw[:50] + ')'
239 self.text.raw[:50] + ')'
@@ -239,16 +246,15 b' class Post(models.Model):'
239 return title
246 return title
240
247
241 def _get_replies(self):
248 def _get_replies(self):
242 return Post.objects.filter(parent=self.id)
249 return self.replies
243
250
244 def get_reply_count(self):
251 def get_reply_count(self):
245 return self._get_replies().count()
252 return self.replies.count()
246
253
247 def get_images_count(self):
254 def get_images_count(self):
248 images_count = 1 if self.image else 0
255 images_count = 1 if self.image else 0
249
256
250 replies = self._get_replies()
257 for reply in self.replies:
251 for reply in replies:
252 if reply.image:
258 if reply.image:
253 images_count += 1
259 images_count += 1
254
260
@@ -257,9 +263,9 b' class Post(models.Model):'
257 def can_bump(self):
263 def can_bump(self):
258 """Check if the thread can be bumped by replying"""
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 def get_last_replies(self):
270 def get_last_replies(self):
265 if settings.LAST_REPLIES_COUNT > 0:
271 if settings.LAST_REPLIES_COUNT > 0:
@@ -268,8 +274,8 b' class Post(models.Model):'
268 if reply_count > 0:
274 if reply_count > 0:
269 reply_count_to_show = min(settings.LAST_REPLIES_COUNT,
275 reply_count_to_show = min(settings.LAST_REPLIES_COUNT,
270 reply_count)
276 reply_count)
271 last_replies = self._get_replies()[reply_count
277 last_replies = self.replies.all()[reply_count -
272 - reply_count_to_show:]
278 reply_count_to_show:]
273
279
274 return last_replies
280 return last_replies
275
281
@@ -219,6 +219,7 b' def jump_to_post(request, post_id):'
219 if boards.models.NO_PARENT == post.parent:
219 if boards.models.NO_PARENT == post.parent:
220 return redirect(thread, post_id=post.id)
220 return redirect(thread, post_id=post.id)
221 else:
221 else:
222 # TODO Change this code to not use 'parent' field anymore
222 parent_thread = get_object_or_404(Post, id=post.parent)
223 parent_thread = get_object_or_404(Post, id=post.parent)
223 return redirect(reverse(thread, kwargs={'post_id': parent_thread.id})
224 return redirect(reverse(thread, kwargs={'post_id': parent_thread.id})
224 + '#' + str(post.id))
225 + '#' + str(post.id))
General Comments 0
You need to be logged in to leave comments. Login now