##// END OF EJS Templates
Allow connecting post to many threads
neko259 -
r979:34912b48 default
parent child Browse files
Show More
@@ -0,0 +1,30 b''
1 # -*- coding: utf-8 -*-
2 from __future__ import unicode_literals
3
4 from django.db import models, migrations
5
6
7 class Migration(migrations.Migration):
8
9 def thread_to_threads(apps, schema_editor):
10 Post = apps.get_model('boards', 'Post')
11 for post in Post.objects.all():
12 post.threads.add(post.thread_new)
13
14 dependencies = [
15 ('boards', '0006_auto_20150201_2130'),
16 ]
17
18 operations = [
19 migrations.AddField(
20 model_name='post',
21 name='threads',
22 field=models.ManyToManyField(to='boards.Thread'),
23 preserve_default=True,
24 ),
25 migrations.RunPython(thread_to_threads),
26 migrations.RemoveField(
27 model_name='post',
28 name='thread_new',
29 ),
30 ]
@@ -0,0 +1,19 b''
1 # -*- coding: utf-8 -*-
2 from __future__ import unicode_literals
3
4 from django.db import models, migrations
5
6
7 class Migration(migrations.Migration):
8
9 dependencies = [
10 ('boards', '0007_auto_20150205_1247'),
11 ]
12
13 operations = [
14 migrations.AlterField(
15 model_name='post',
16 name='threads',
17 field=models.ManyToManyField(to='boards.Thread', db_index=True),
18 ),
19 ]
@@ -10,7 +10,7 b' class PostAdmin(admin.ModelAdmin):'
10 list_filter = ('pub_time',)
10 list_filter = ('pub_time',)
11 search_fields = ('id', 'title', 'text')
11 search_fields = ('id', 'title', 'text')
12 exclude = ('referenced_posts', 'refmap')
12 exclude = ('referenced_posts', 'refmap')
13 readonly_fields = ('poster_ip', 'thread_new')
13 readonly_fields = ('poster_ip', 'threads')
14
14
15 def ban_poster(self, request, queryset):
15 def ban_poster(self, request, queryset):
16 bans = 0
16 bans = 0
@@ -90,11 +90,11 b' class PostManager(models.Manager):'
90 post = self.create(title=title,
90 post = self.create(title=title,
91 text=pre_text,
91 text=pre_text,
92 pub_time=posting_time,
92 pub_time=posting_time,
93 thread_new=thread,
94 poster_ip=ip,
93 poster_ip=ip,
95 poster_user_agent=UNKNOWN_UA, # TODO Get UA at
94 poster_user_agent=UNKNOWN_UA, # TODO Get UA at
96 # last!
95 # last!
97 last_edit_time=posting_time)
96 last_edit_time=posting_time)
97 post.threads.add(thread)
98
98
99 logger = logging.getLogger('boards.post.create')
99 logger = logging.getLogger('boards.post.create')
100
100
@@ -212,8 +212,6 b' class Post(models.Model, Viewable):'
212 poster_ip = models.GenericIPAddressField()
212 poster_ip = models.GenericIPAddressField()
213 poster_user_agent = models.TextField()
213 poster_user_agent = models.TextField()
214
214
215 thread_new = models.ForeignKey('Thread', null=True, default=None,
216 db_index=True)
217 last_edit_time = models.DateTimeField()
215 last_edit_time = models.DateTimeField()
218
216
219 referenced_posts = models.ManyToManyField('Post', symmetrical=False,
217 referenced_posts = models.ManyToManyField('Post', symmetrical=False,
@@ -221,6 +219,7 b' class Post(models.Model, Viewable):'
221 blank=True, related_name='rfp+',
219 blank=True, related_name='rfp+',
222 db_index=True)
220 db_index=True)
223 refmap = models.TextField(null=True, blank=True)
221 refmap = models.TextField(null=True, blank=True)
222 threads = models.ManyToManyField('Thread', db_index=True)
224
223
225 def __str__(self):
224 def __str__(self):
226 return 'P#{}/{}'.format(self.id, self.title)
225 return 'P#{}/{}'.format(self.id, self.title)
@@ -300,15 +299,19 b' class Post(models.Model, Viewable):'
300
299
301 return link
300 return link
302
301
302 # TODO This must be removed after full transition to multiple threads
303 def get_thread(self):
303 def get_thread(self):
304 return self.get_threads().first()
305
306 def get_threads(self):
304 """
307 """
305 Gets post's thread.
308 Gets post's thread.
306 """
309 """
307
310
308 return self.thread_new
311 return self.threads
309
312
310 def get_referenced_posts(self):
313 def get_referenced_posts(self):
311 return self.referenced_posts.only('id', 'thread_new')
314 return self.referenced_posts.only('id', 'threads')
312
315
313 def get_view(self, moderator=False, need_open_link=False,
316 def get_view(self, moderator=False, need_open_link=False,
314 truncated=False, *args, **kwargs):
317 truncated=False, *args, **kwargs):
@@ -389,7 +392,7 b' class Post(models.Model, Viewable):'
389 post_json['image_preview'] = post_image.image.url_200x150
392 post_json['image_preview'] = post_image.image.url_200x150
390 if include_last_update:
393 if include_last_update:
391 post_json['bump_time'] = datetime_to_epoch(
394 post_json['bump_time'] = datetime_to_epoch(
392 self.thread_new.bump_time)
395 self.get_thread().bump_time)
393 return post_json
396 return post_json
394
397
395 def send_to_websocket(self, request, recursive=True):
398 def send_to_websocket(self, request, recursive=True):
@@ -422,7 +425,7 b' class Post(models.Model, Viewable):'
422
425
423 # If post is in this thread, its thread was already notified.
426 # If post is in this thread, its thread was already notified.
424 # Otherwise, notify its thread separately.
427 # Otherwise, notify its thread separately.
425 if ref_post.thread_new_id != thread_id:
428 if ref_post.get_thread().id != thread_id:
426 ref_post.send_to_websocket(request, recursive=False)
429 ref_post.send_to_websocket(request, recursive=False)
427
430
428 def save(self, force_insert=False, force_update=False, using=None,
431 def save(self, force_insert=False, force_update=False, using=None,
@@ -120,7 +120,7 b' class Thread(models.Model):'
120 Gets sorted thread posts
120 Gets sorted thread posts
121 """
121 """
122
122
123 query = Post.objects.filter(thread_new=self)
123 query = Post.objects.filter(threads__in=[self])
124 query = query.order_by('pub_time').prefetch_related('images')
124 query = query.order_by('pub_time').prefetch_related('images')
125 if view_fields_only:
125 if view_fields_only:
126 query = query.defer('poster_user_agent')
126 query = query.defer('poster_user_agent')
@@ -18,7 +18,7 b' class ApiTest(TestCase):'
18
18
19 # Check the exact timestamp post was added
19 # Check the exact timestamp post was added
20 empty_response = api.api_get_threaddiff(
20 empty_response = api.api_get_threaddiff(
21 MockRequest(), str(opening_post.thread_new.id), str(last_edit_time))
21 MockRequest(), str(opening_post.get_thread().id), str(last_edit_time))
22 diff = simplejson.loads(empty_response.content)
22 diff = simplejson.loads(empty_response.content)
23 self.assertEqual(0, len(diff['added']),
23 self.assertEqual(0, len(diff['added']),
24 'There must be no added posts in the diff.')
24 'There must be no added posts in the diff.')
@@ -27,11 +27,11 b' class ApiTest(TestCase):'
27
27
28 reply = Post.objects.create_post(title='',
28 reply = Post.objects.create_post(title='',
29 text='[post]%d[/post]\ntext' % opening_post.id,
29 text='[post]%d[/post]\ntext' % opening_post.id,
30 thread=opening_post.thread_new)
30 thread=opening_post.get_thread())
31
31
32 # Check the timestamp before post was added
32 # Check the timestamp before post was added
33 response = api.api_get_threaddiff(
33 response = api.api_get_threaddiff(
34 MockRequest(), str(opening_post.thread_new.id), str(last_edit_time))
34 MockRequest(), str(opening_post.get_thread().id), str(last_edit_time))
35 diff = simplejson.loads(response.content)
35 diff = simplejson.loads(response.content)
36 self.assertEqual(1, len(diff['added']),
36 self.assertEqual(1, len(diff['added']),
37 'There must be 1 added posts in the diff.')
37 'There must be 1 added posts in the diff.')
@@ -39,7 +39,7 b' class ApiTest(TestCase):'
39 'There must be 1 updated posts in the diff.')
39 'There must be 1 updated posts in the diff.')
40
40
41 empty_response = api.api_get_threaddiff(MockRequest(),
41 empty_response = api.api_get_threaddiff(MockRequest(),
42 str(opening_post.thread_new.id),
42 str(opening_post.get_thread().id),
43 str(datetime_to_epoch(reply.last_edit_time)))
43 str(datetime_to_epoch(reply.last_edit_time)))
44 diff = simplejson.loads(empty_response.content)
44 diff = simplejson.loads(empty_response.content)
45 self.assertEqual(0, len(diff['added']),
45 self.assertEqual(0, len(diff['added']),
@@ -48,10 +48,10 b' def api_get_threaddiff(request, thread_i'
48 'updated': [],
48 'updated': [],
49 'last_update': None,
49 'last_update': None,
50 }
50 }
51 added_posts = Post.objects.filter(thread_new=thread,
51 added_posts = Post.objects.filter(threads__in=[thread],
52 pub_time__gt=filter_time) \
52 pub_time__gt=filter_time) \
53 .order_by('pub_time')
53 .order_by('pub_time')
54 updated_posts = Post.objects.filter(thread_new=thread,
54 updated_posts = Post.objects.filter(threads__in=[thread],
55 pub_time__lte=filter_time,
55 pub_time__lte=filter_time,
56 last_edit_time__gt=filter_time)
56 last_edit_time__gt=filter_time)
57
57
@@ -37,7 +37,7 b' class ThreadView(BaseBoardView, PostMixi'
37
37
38 def get(self, request, post_id, form: PostForm=None):
38 def get(self, request, post_id, form: PostForm=None):
39 try:
39 try:
40 opening_post = Post.objects.filter(id=post_id).only('thread_new')[0]
40 opening_post = Post.objects.filter(id=post_id).first()
41 except IndexError:
41 except IndexError:
42 raise Http404
42 raise Http404
43
43
General Comments 0
You need to be logged in to leave comments. Login now