##// END OF EJS Templates
Code cleanup part 2
neko259 -
r722:0a4dc1c4 default
parent child Browse files
Show More
@@ -1,22 +1,22 b''
1 from django.core.paginator import Paginator
1 __author__ = 'neko259'
2
2
3 __author__ = 'neko259'
3 from django.core.paginator import Paginator
4
4
5 PAGINATOR_LOOKAROUND_SIZE = 3
5 PAGINATOR_LOOKAROUND_SIZE = 3
6
6
7
7
8 def get_paginator(*args, **kwargs):
8 def get_paginator(*args, **kwargs):
9 return DividedPaginator(*args, **kwargs)
9 return DividedPaginator(*args, **kwargs)
10
10
11
11
12 class DividedPaginator(Paginator):
12 class DividedPaginator(Paginator):
13
13
14 lookaround_size = PAGINATOR_LOOKAROUND_SIZE
14 lookaround_size = PAGINATOR_LOOKAROUND_SIZE
15 current_page = 0
15 current_page = 0
16
16
17 def center_range(self):
17 def center_range(self):
18 index = self.page_range.index(self.current_page)
18 index = self.page_range.index(self.current_page)
19
19
20 start = max(0, index - self.lookaround_size)
20 start = max(0, index - self.lookaround_size)
21 end = min(len(self.page_range), index + self.lookaround_size + 1)
21 end = min(len(self.page_range), index + self.lookaround_size + 1)
22 return self.page_range[start:end] No newline at end of file
22 return self.page_range[start:end]
@@ -1,133 +1,138 b''
1 import string
1 import string
2
2
3 from django.db import transaction
3 from django.db import transaction
4 from django.shortcuts import render, redirect
4 from django.shortcuts import render, redirect
5
5
6 from boards import utils, settings
6 from boards import utils, settings
7 from boards.abstracts.paginator import get_paginator
7 from boards.abstracts.paginator import get_paginator
8 from boards.forms import ThreadForm, PlainErrorList
8 from boards.forms import ThreadForm, PlainErrorList
9 from boards.models import Post, Thread, Ban, Tag
9 from boards.models import Post, Thread, Ban, Tag
10 from boards.views.banned import BannedView
10 from boards.views.banned import BannedView
11 from boards.views.base import BaseBoardView, PARAMETER_FORM
11 from boards.views.base import BaseBoardView, CONTEXT_FORM
12 from boards.views.posting_mixin import PostMixin
12 from boards.views.posting_mixin import PostMixin
13
13
14 FORM_TAGS = 'tags'
15 FORM_TEXT = 'text'
16 FORM_TITLE = 'title'
17 FORM_IMAGE = 'image'
18
14 TAG_DELIMITER = ' '
19 TAG_DELIMITER = ' '
15
20
16 PARAMETER_CURRENT_PAGE = 'current_page'
21 PARAMETER_CURRENT_PAGE = 'current_page'
17 PARAMETER_PAGINATOR = 'paginator'
22 PARAMETER_PAGINATOR = 'paginator'
18 PARAMETER_THREADS = 'threads'
23 PARAMETER_THREADS = 'threads'
19
24
20 TEMPLATE = 'boards/posting_general.html'
25 TEMPLATE = 'boards/posting_general.html'
21 DEFAULT_PAGE = 1
26 DEFAULT_PAGE = 1
22
27
23
28
24 class AllThreadsView(PostMixin, BaseBoardView):
29 class AllThreadsView(PostMixin, BaseBoardView):
25
30
26 user = None
31 user = None
27
32
28 def get(self, request, page=DEFAULT_PAGE, form=None):
33 def get(self, request, page=DEFAULT_PAGE, form=None):
29 context = self.get_context_data(request=request)
34 context = self.get_context_data(request=request)
30
35
31 self.user = utils.get_user(request)
36 self.user = utils.get_user(request)
32
37
33 if not form:
38 if not form:
34 form = ThreadForm(error_class=PlainErrorList)
39 form = ThreadForm(error_class=PlainErrorList)
35
40
36 paginator = get_paginator(self.get_threads(),
41 paginator = get_paginator(self.get_threads(),
37 settings.THREADS_PER_PAGE)
42 settings.THREADS_PER_PAGE)
38 paginator.current_page = int(page)
43 paginator.current_page = int(page)
39
44
40 threads = paginator.page(page).object_list
45 threads = paginator.page(page).object_list
41
46
42 context[PARAMETER_THREADS] = threads
47 context[PARAMETER_THREADS] = threads
43 context[PARAMETER_FORM] = form
48 context[CONTEXT_FORM] = form
44
49
45 self._get_page_context(paginator, context, page)
50 self._get_page_context(paginator, context, page)
46
51
47 return render(request, TEMPLATE, context)
52 return render(request, TEMPLATE, context)
48
53
49 def post(self, request, page=DEFAULT_PAGE):
54 def post(self, request, page=DEFAULT_PAGE):
50 form = ThreadForm(request.POST, request.FILES,
55 form = ThreadForm(request.POST, request.FILES,
51 error_class=PlainErrorList)
56 error_class=PlainErrorList)
52 form.session = request.session
57 form.session = request.session
53
58
54 if form.is_valid():
59 if form.is_valid():
55 return self.create_thread(request, form)
60 return self.create_thread(request, form)
56 if form.need_to_ban:
61 if form.need_to_ban:
57 # Ban user because he is suspected to be a bot
62 # Ban user because he is suspected to be a bot
58 self._ban_current_user(request)
63 self._ban_current_user(request)
59
64
60 return self.get(request, page, form)
65 return self.get(request, page, form)
61
66
62 @staticmethod
67 @staticmethod
63 def _get_page_context(paginator, context, page):
68 def _get_page_context(paginator, context, page):
64 """
69 """
65 Get pagination context variables
70 Get pagination context variables
66 """
71 """
67
72
68 context[PARAMETER_PAGINATOR] = paginator
73 context[PARAMETER_PAGINATOR] = paginator
69 context[PARAMETER_CURRENT_PAGE] = paginator.page(int(page))
74 context[PARAMETER_CURRENT_PAGE] = paginator.page(int(page))
70
75
71 @staticmethod
76 @staticmethod
72 def parse_tags_string(tag_strings):
77 def parse_tags_string(tag_strings):
73 """
78 """
74 Parses tag list string and returns tag object list.
79 Parses tag list string and returns tag object list.
75 """
80 """
76
81
77 tags = []
82 tags = []
78
83
79 if tag_strings:
84 if tag_strings:
80 tag_strings = tag_strings.split(TAG_DELIMITER)
85 tag_strings = tag_strings.split(TAG_DELIMITER)
81 for tag_name in tag_strings:
86 for tag_name in tag_strings:
82 tag_name = string.lower(tag_name.strip())
87 tag_name = string.lower(tag_name.strip())
83 if len(tag_name) > 0:
88 if len(tag_name) > 0:
84 tag, created = Tag.objects.get_or_create(name=tag_name)
89 tag, created = Tag.objects.get_or_create(name=tag_name)
85 tags.append(tag)
90 tags.append(tag)
86
91
87 return tags
92 return tags
88
93
89 @transaction.atomic
94 @transaction.atomic
90 def create_thread(self, request, form, html_response=True):
95 def create_thread(self, request, form, html_response=True):
91 """
96 """
92 Creates a new thread with an opening post.
97 Creates a new thread with an opening post.
93 """
98 """
94
99
95 ip = utils.get_client_ip(request)
100 ip = utils.get_client_ip(request)
96 is_banned = Ban.objects.filter(ip=ip).exists()
101 is_banned = Ban.objects.filter(ip=ip).exists()
97
102
98 if is_banned:
103 if is_banned:
99 if html_response:
104 if html_response:
100 return redirect(BannedView().as_view())
105 return redirect(BannedView().as_view())
101 else:
106 else:
102 return
107 return
103
108
104 data = form.cleaned_data
109 data = form.cleaned_data
105
110
106 title = data['title']
111 title = data[FORM_TITLE]
107 text = data['text']
112 text = data[FORM_TEXT]
108
113
109 text = self._remove_invalid_links(text)
114 text = self._remove_invalid_links(text)
110
115
111 if 'image' in data.keys():
116 if FORM_IMAGE in data.keys():
112 image = data['image']
117 image = data[FORM_IMAGE]
113 else:
118 else:
114 image = None
119 image = None
115
120
116 tag_strings = data['tags']
121 tag_strings = data[FORM_TAGS]
117
122
118 tags = self.parse_tags_string(tag_strings)
123 tags = self.parse_tags_string(tag_strings)
119
124
120 post = Post.objects.create_post(title=title, text=text, ip=ip,
125 post = Post.objects.create_post(title=title, text=text, ip=ip,
121 image=image, tags=tags,
126 image=image, tags=tags,
122 user=utils.get_user(request))
127 user=utils.get_user(request))
123
128
124 if html_response:
129 if html_response:
125 return redirect(post.get_url())
130 return redirect(post.get_url())
126
131
127 def get_threads(self):
132 def get_threads(self):
128 """
133 """
129 Gets list of threads that will be shown on a page.
134 Gets list of threads that will be shown on a page.
130 """
135 """
131
136
132 return Thread.objects.all().order_by('-bump_time')\
137 return Thread.objects.all().order_by('-bump_time')\
133 .exclude(tags__in=self.user.hidden_tags.all())
138 .exclude(tags__in=self.user.hidden_tags.all())
@@ -1,35 +1,35 b''
1 from django.db import transaction
1 from django.db import transaction
2 from django.template import RequestContext
2 from django.template import RequestContext
3 from django.views.generic import View
3 from django.views.generic import View
4
4
5 from boards import utils
5 from boards import utils
6 from boards.models.user import Ban
6 from boards.models.user import Ban
7
7
8
8
9 BAN_REASON_SPAM = 'Autoban: spam bot'
9 BAN_REASON_SPAM = 'Autoban: spam bot'
10
10
11 PARAMETER_FORM = 'form'
11 CONTEXT_FORM = 'form'
12
12
13
13
14 class BaseBoardView(View):
14 class BaseBoardView(View):
15
15
16 def get_context_data(self, **kwargs):
16 def get_context_data(self, **kwargs):
17 request = kwargs['request']
17 request = kwargs['request']
18 # context = self._default_context(request)
18 # context = self._default_context(request)
19 context = RequestContext(request)
19 context = RequestContext(request)
20
20
21 return context
21 return context
22
22
23 @transaction.atomic
23 @transaction.atomic
24 def _ban_current_user(self, request):
24 def _ban_current_user(self, request):
25 """
25 """
26 Add current user to the IP ban list
26 Add current user to the IP ban list
27 """
27 """
28
28
29 ip = utils.get_client_ip(request)
29 ip = utils.get_client_ip(request)
30 ban, created = Ban.objects.get_or_create(ip=ip)
30 ban, created = Ban.objects.get_or_create(ip=ip)
31 if created:
31 if created:
32 ban.can_read = False
32 ban.can_read = False
33 ban.reason = BAN_REASON_SPAM
33 ban.reason = BAN_REASON_SPAM
34 ban.save()
34 ban.save()
35
35
@@ -1,30 +1,30 b''
1 from django.shortcuts import render, redirect
1 from django.shortcuts import render, redirect
2 from boards.forms import LoginForm, PlainErrorList
2 from boards.forms import LoginForm, PlainErrorList
3 from boards.models import User
3 from boards.models import User
4 from boards.views.base import BaseBoardView, PARAMETER_FORM
4 from boards.views.base import BaseBoardView, CONTEXT_FORM
5
5
6 __author__ = 'neko259'
6 __author__ = 'neko259'
7
7
8
8
9 class LoginView(BaseBoardView):
9 class LoginView(BaseBoardView):
10
10
11 def get(self, request, form=None):
11 def get(self, request, form=None):
12 context = self.get_context_data(request=request)
12 context = self.get_context_data(request=request)
13
13
14 if not form:
14 if not form:
15 form = LoginForm()
15 form = LoginForm()
16 context[PARAMETER_FORM] = form
16 context[CONTEXT_FORM] = form
17
17
18 return render(request, 'boards/login.html', context)
18 return render(request, 'boards/login.html', context)
19
19
20 def post(self, request):
20 def post(self, request):
21 form = LoginForm(request.POST, request.FILES,
21 form = LoginForm(request.POST, request.FILES,
22 error_class=PlainErrorList)
22 error_class=PlainErrorList)
23 form.session = request.session
23 form.session = request.session
24
24
25 if form.is_valid():
25 if form.is_valid():
26 user = User.objects.get(user_id=form.cleaned_data['user_id'])
26 user = User.objects.get(user_id=form.cleaned_data['user_id'])
27 request.session['user_id'] = user.id
27 request.session['user_id'] = user.id
28 return redirect('index')
28 return redirect('index')
29 else:
29 else:
30 return self.get(request, form)
30 return self.get(request, form)
@@ -1,53 +1,53 b''
1 from django.db import transaction
1 from django.db import transaction
2 from django.shortcuts import render, redirect
2 from django.shortcuts import render, redirect
3 from boards import utils
3 from boards import utils
4
4
5 from boards.views.base import BaseBoardView, PARAMETER_FORM
5 from boards.views.base import BaseBoardView, CONTEXT_FORM
6 from boards.forms import SettingsForm, ModeratorSettingsForm, PlainErrorList
6 from boards.forms import SettingsForm, ModeratorSettingsForm, PlainErrorList
7 from boards.models.post import SETTING_MODERATE
7 from boards.models.post import SETTING_MODERATE
8
8
9
9
10 class SettingsView(BaseBoardView):
10 class SettingsView(BaseBoardView):
11
11
12 def get(self, request):
12 def get(self, request):
13 context = self.get_context_data(request=request)
13 context = self.get_context_data(request=request)
14 user = utils.get_user(request)
14 user = utils.get_user(request)
15 is_moderator = user.is_moderator()
15 is_moderator = user.is_moderator()
16
16
17 selected_theme = utils.get_theme(request, user)
17 selected_theme = utils.get_theme(request, user)
18
18
19 if is_moderator:
19 if is_moderator:
20 form = ModeratorSettingsForm(initial={
20 form = ModeratorSettingsForm(initial={
21 'theme': selected_theme,
21 'theme': selected_theme,
22 'moderate': user.get_setting(SETTING_MODERATE) and \
22 'moderate': user.get_setting(SETTING_MODERATE) and \
23 user.is_moderator()
23 user.is_moderator()
24 }, error_class=PlainErrorList)
24 }, error_class=PlainErrorList)
25 else:
25 else:
26 form = SettingsForm(initial={'theme': selected_theme},
26 form = SettingsForm(initial={'theme': selected_theme},
27 error_class=PlainErrorList)
27 error_class=PlainErrorList)
28
28
29 context[PARAMETER_FORM] = form
29 context[CONTEXT_FORM] = form
30
30
31 return render(request, 'boards/settings.html', context)
31 return render(request, 'boards/settings.html', context)
32
32
33 def post(self, request):
33 def post(self, request):
34 user = utils.get_user(request)
34 user = utils.get_user(request)
35 is_moderator = user.is_moderator()
35 is_moderator = user.is_moderator()
36
36
37 with transaction.atomic():
37 with transaction.atomic():
38 if is_moderator:
38 if is_moderator:
39 form = ModeratorSettingsForm(request.POST,
39 form = ModeratorSettingsForm(request.POST,
40 error_class=PlainErrorList)
40 error_class=PlainErrorList)
41 else:
41 else:
42 form = SettingsForm(request.POST, error_class=PlainErrorList)
42 form = SettingsForm(request.POST, error_class=PlainErrorList)
43
43
44 if form.is_valid():
44 if form.is_valid():
45 selected_theme = form.cleaned_data['theme']
45 selected_theme = form.cleaned_data['theme']
46
46
47 user.save_setting('theme', selected_theme)
47 user.save_setting('theme', selected_theme)
48
48
49 if is_moderator:
49 if is_moderator:
50 moderate = form.cleaned_data['moderate']
50 moderate = form.cleaned_data['moderate']
51 user.save_setting(SETTING_MODERATE, moderate)
51 user.save_setting(SETTING_MODERATE, moderate)
52
52
53 return redirect('settings')
53 return redirect('settings')
@@ -1,132 +1,144 b''
1 from django.core.urlresolvers import reverse
1 from django.core.urlresolvers import reverse
2 from django.db import transaction
2 from django.db import transaction
3 from django.http import Http404
3 from django.http import Http404
4 from django.shortcuts import get_object_or_404, render, redirect
4 from django.shortcuts import get_object_or_404, render, redirect
5 from django.views.generic.edit import FormMixin
5 from django.views.generic.edit import FormMixin
6
6
7 from boards import utils, settings
7 from boards import utils, settings
8 from boards.forms import PostForm, PlainErrorList
8 from boards.forms import PostForm, PlainErrorList
9 from boards.models import Post, Ban
9 from boards.models import Post, Ban
10 from boards.views.banned import BannedView
10 from boards.views.banned import BannedView
11 from boards.views.base import BaseBoardView, PARAMETER_FORM
11 from boards.views.base import BaseBoardView, CONTEXT_FORM
12 from boards.views.posting_mixin import PostMixin
12 from boards.views.posting_mixin import PostMixin
13
13
14 TEMPLATE_GALLERY = 'boards/thread_gallery.html'
15 TEMPLATE_NORMAL = 'boards/thread.html'
16
17 CONTEXT_POSTS = 'posts'
18 CONTEXT_OP = 'opening_post'
19 CONTEXT_BUMPLIMIT_PRG = 'bumplimit_progress'
20 CONTEXT_POSTS_LEFT = 'posts_left'
21 CONTEXT_LASTUPDATE = "last_update"
22 CONTEXT_MAX_REPLIES = 'max_replies'
23 CONTEXT_THREAD = 'thread'
24 CONTEXT_BUMPABLE = 'bumpable'
25
26 FORM_TITLE = 'title'
27 FORM_TEXT = 'text'
28 FORM_IMAGE = 'image'
14
29
15 MODE_GALLERY = 'gallery'
30 MODE_GALLERY = 'gallery'
16 MODE_NORMAL = 'normal'
31 MODE_NORMAL = 'normal'
17
32
18 PARAMETER_MAX_REPLIES = 'max_replies'
19 PARAMETER_THREAD = 'thread'
20 PARAMETER_BUMPABLE = 'bumpable'
21
22
33
23 class ThreadView(BaseBoardView, PostMixin, FormMixin):
34 class ThreadView(BaseBoardView, PostMixin, FormMixin):
24
35
25 def get(self, request, post_id, mode=MODE_NORMAL, form=None):
36 def get(self, request, post_id, mode=MODE_NORMAL, form=None):
26 try:
37 try:
27 opening_post = Post.objects.filter(id=post_id).only('thread_new')[0]
38 opening_post = Post.objects.filter(id=post_id).only('thread_new')[0]
28 except IndexError:
39 except IndexError:
29 raise Http404
40 raise Http404
30
41
31 # If this is not OP, don't show it as it is
42 # If this is not OP, don't show it as it is
32 if not opening_post or not opening_post.is_opening():
43 if not opening_post or not opening_post.is_opening():
33 raise Http404
44 raise Http404
34
45
35 if not form:
46 if not form:
36 form = PostForm(error_class=PlainErrorList)
47 form = PostForm(error_class=PlainErrorList)
37
48
38 thread_to_show = opening_post.get_thread()
49 thread_to_show = opening_post.get_thread()
39
50
40 context = self.get_context_data(request=request)
51 context = self.get_context_data(request=request)
41
52
42 context[PARAMETER_FORM] = form
53 context[CONTEXT_FORM] = form
43 context["last_update"] = utils.datetime_to_epoch(
54 context[CONTEXT_LASTUPDATE] = utils.datetime_to_epoch(
44 thread_to_show.last_edit_time)
55 thread_to_show.last_edit_time)
45 context[PARAMETER_THREAD] = thread_to_show
56 context[CONTEXT_THREAD] = thread_to_show
46 context[PARAMETER_MAX_REPLIES] = settings.MAX_POSTS_PER_THREAD
57 context[CONTEXT_MAX_REPLIES] = settings.MAX_POSTS_PER_THREAD
47
58
48 if MODE_NORMAL == mode:
59 if MODE_NORMAL == mode:
49 context[PARAMETER_BUMPABLE] = thread_to_show.can_bump()
60 bumpable = thread_to_show.can_bump()
50 if context[PARAMETER_BUMPABLE]:
61 context[CONTEXT_BUMPABLE] = bumpable
51 context['posts_left'] = settings.MAX_POSTS_PER_THREAD \
62 if bumpable:
52 - thread_to_show.get_reply_count()
63 left_posts = settings.MAX_POSTS_PER_THREAD \
53 context['bumplimit_progress'] = str(
64 - thread_to_show.get_reply_count()
54 float(context['posts_left']) /
65 context[CONTEXT_POSTS_LEFT] = left_posts
55 settings.MAX_POSTS_PER_THREAD * 100)
66 context[CONTEXT_BUMPLIMIT_PRG] = str(
67 float(left_posts) / settings.MAX_POSTS_PER_THREAD * 100)
56
68
57 context['opening_post'] = opening_post
69 context[CONTEXT_OP] = opening_post
58
70
59 document = 'boards/thread.html'
71 document = TEMPLATE_NORMAL
60 elif MODE_GALLERY == mode:
72 elif MODE_GALLERY == mode:
61 context['posts'] = thread_to_show.get_replies_with_images(
73 context[CONTEXT_POSTS] = thread_to_show.get_replies_with_images(
62 view_fields_only=True)
74 view_fields_only=True)
63
75
64 document = 'boards/thread_gallery.html'
76 document = TEMPLATE_GALLERY
65 else:
77 else:
66 raise Http404
78 raise Http404
67
79
68 return render(request, document, context)
80 return render(request, document, context)
69
81
70 def post(self, request, post_id, mode=MODE_NORMAL):
82 def post(self, request, post_id, mode=MODE_NORMAL):
71 opening_post = get_object_or_404(Post, id=post_id)
83 opening_post = get_object_or_404(Post, id=post_id)
72
84
73 # If this is not OP, don't show it as it is
85 # If this is not OP, don't show it as it is
74 if not opening_post.is_opening():
86 if not opening_post.is_opening():
75 raise Http404
87 raise Http404
76
88
77 if not opening_post.get_thread().archived:
89 if not opening_post.get_thread().archived:
78 form = PostForm(request.POST, request.FILES,
90 form = PostForm(request.POST, request.FILES,
79 error_class=PlainErrorList)
91 error_class=PlainErrorList)
80 form.session = request.session
92 form.session = request.session
81
93
82 if form.is_valid():
94 if form.is_valid():
83 return self.new_post(request, form, opening_post)
95 return self.new_post(request, form, opening_post)
84 if form.need_to_ban:
96 if form.need_to_ban:
85 # Ban user because he is suspected to be a bot
97 # Ban user because he is suspected to be a bot
86 self._ban_current_user(request)
98 self._ban_current_user(request)
87
99
88 return self.get(request, post_id, mode, form)
100 return self.get(request, post_id, mode, form)
89
101
90 @transaction.atomic
102 @transaction.atomic
91 def new_post(self, request, form, opening_post=None, html_response=True):
103 def new_post(self, request, form, opening_post=None, html_response=True):
92 """Add a new post (in thread or as a reply)."""
104 """Add a new post (in thread or as a reply)."""
93
105
94 ip = utils.get_client_ip(request)
106 ip = utils.get_client_ip(request)
95 is_banned = Ban.objects.filter(ip=ip).exists()
107 is_banned = Ban.objects.filter(ip=ip).exists()
96
108
97 if is_banned:
109 if is_banned:
98 if html_response:
110 if html_response:
99 return redirect(BannedView().as_view())
111 return redirect(BannedView().as_view())
100 else:
112 else:
101 return None
113 return None
102
114
103 data = form.cleaned_data
115 data = form.cleaned_data
104
116
105 title = data['title']
117 title = data[FORM_TITLE]
106 text = data['text']
118 text = data[FORM_TEXT]
107
119
108 text = self._remove_invalid_links(text)
120 text = self._remove_invalid_links(text)
109
121
110 if 'image' in data.keys():
122 if FORM_IMAGE in data.keys():
111 image = data['image']
123 image = data[FORM_IMAGE]
112 else:
124 else:
113 image = None
125 image = None
114
126
115 tags = []
127 tags = []
116
128
117 post_thread = opening_post.get_thread()
129 post_thread = opening_post.get_thread()
118
130
119 post = Post.objects.create_post(title=title, text=text, ip=ip,
131 post = Post.objects.create_post(title=title, text=text, ip=ip,
120 thread=post_thread, image=image,
132 thread=post_thread, image=image,
121 tags=tags,
133 tags=tags,
122 user=utils.get_user(request))
134 user=utils.get_user(request))
123
135
124 thread_to_show = (opening_post.id if opening_post else post.id)
136 thread_to_show = (opening_post.id if opening_post else post.id)
125
137
126 if html_response:
138 if html_response:
127 if opening_post:
139 if opening_post:
128 return redirect(reverse(
140 return redirect(
129 'thread',
141 reverse('thread', kwargs={'post_id': thread_to_show})
130 kwargs={'post_id': thread_to_show}) + '#' + str(post.id))
142 + '#' + str(post.id))
131 else:
143 else:
132 return post
144 return post
General Comments 0
You need to be logged in to leave comments. Login now