def question( request, id ): #refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it todo: convert this view into class """ #process url parameters #todo: fix inheritance of sort method from questions #before = datetime.datetime.now() form = ShowQuestionForm(request.GET) form.full_clean() #always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] answer_sort_method = form.cleaned_data['answer_sort_method'] #load question and maybe refuse showing deleted question #if the question does not exist - try mapping to old questions #and and if it is not found again - then give up try: question_post = models.Post.objects.filter( post_type='question', id=id).select_related('thread')[0] except IndexError: # Handle URL mapping - from old Q/A/C/ URLs to the new one try: question_post = models.Post.objects.filter( post_type='question', old_question_id=id).select_related('thread')[0] except IndexError: raise Http404 if show_answer: try: old_answer = models.Post.objects.get_answers().get( old_answer_id=show_answer) return HttpResponseRedirect(old_answer.get_absolute_url()) except models.Post.DoesNotExist: pass elif show_comment: try: old_comment = models.Post.objects.get_comments().get( old_comment_id=show_comment) return HttpResponseRedirect(old_comment.get_absolute_url()) except models.Post.DoesNotExist: pass try: question_post.assert_is_visible_to(request.user) except exceptions.QuestionHidden, error: request.user.message_set.create(message=unicode(error)) return HttpResponseRedirect(reverse('index'))
def question(request, id):#refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it todo: convert this view into class """ #process url parameters #todo: fix inheritance of sort method from questions #before = datetime.datetime.now() form = ShowQuestionForm(request.REQUEST) form.full_clean()#always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] answer_sort_method = form.cleaned_data['answer_sort_method'] #load question and maybe refuse showing deleted question #if the question does not exist - try mapping to old questions #and and if it is not found again - then give up try: question_post = models.Post.objects.filter( post_type = 'question', id = id ).select_related('thread')[0] except IndexError: # Handle URL mapping - from old Q/A/C/ URLs to the new one try: question_post = models.Post.objects.filter( post_type='question', old_question_id = id ).select_related('thread')[0] except IndexError: raise Http404 if show_answer: try: old_answer = models.Post.objects.get_answers().get(old_answer_id=show_answer) return HttpResponseRedirect(old_answer.get_absolute_url()) except models.Post.DoesNotExist: pass elif show_comment: try: old_comment = models.Post.objects.get_comments().get(old_comment_id=show_comment) return HttpResponseRedirect(old_comment.get_absolute_url()) except models.Post.DoesNotExist: pass try: question_post.assert_is_visible_to(request.user) except exceptions.QuestionHidden, error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index'))
def question(request, id):#refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it """ #process url parameters #todo: fix inheritance of sort method from questions default_sort_method = request.session.get('questions_sort_method', 'votes') form = ShowQuestionForm(request.GET, default_sort_method) form.full_clean()#always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] is_permalink = form.cleaned_data['is_permalink'] answer_sort_method = form.cleaned_data['answer_sort_method'] #resolve comment and answer permalinks #they go first because in theory both can be moved to another question #this block "returns" show_post and assigns actual comment and answer #to show_comment and show_answer variables #in the case if the permalinked items or their parents are gone - redirect #redirect also happens if id of the object's origin post != requested id show_post = None #used for permalinks if show_comment is not None: #if url calls for display of a specific comment, #check that comment exists, that it belongs to #the current question #if it is an answer comment and the answer is hidden - #redirect to the default view of the question #if the question is hidden - redirect to the main page #in addition - if url points to a comment and the comment #is for the answer - we need the answer object try: show_comment = models.Comment.objects.get(id = show_comment) if str(show_comment.get_origin_post().id) != id: return HttpResponseRedirect(show_comment.get_absolute_url()) show_post = show_comment.content_object show_comment.assert_is_visible_to(request.user) except models.Comment.DoesNotExist: error_message = _( 'Sorry, the comment you are looking for has been ' 'deleted and is no longer accessible' ) request.user.message_set.create(message = error_message) return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) except exceptions.AnswerHidden, error: request.user.message_set.create(message = unicode(error)) #use reverse function here because question is not yet loaded return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) except exceptions.QuestionHidden, error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index'))
def question( request, id ): #refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it """ #todo: fix inheritance of sort method from questions default_sort_method = request.session.get('questions_sort_method', 'votes') form = ShowQuestionForm(request.GET, default_sort_method) form.full_clean() #always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] is_permalink = form.cleaned_data['is_permalink'] answer_sort_method = form.cleaned_data['answer_sort_method'] #resolve comment and answer permalinks #they go first because in theory both can be moved to another question #this block "returns" show_post and assigns actual comment and answer #to show_comment and show_answer variables #in the case if the permalinked items or their parents are gone - redirect #redirect also happens if id of the object's origin post != requested id show_post = None #used for permalinks if show_comment is not None: #comments try: show_comment = models.Comment.objects.get(id=show_comment) if str(show_comment.get_origin_post().id) != id: return HttpResponseRedirect(show_comment.get_absolute_url()) show_post = show_comment.content_object show_comment.assert_is_visible_to(request.user) except models.Comment.DoesNotExist: error_message = _( 'Sorry, the comment you are looking for has been ' 'deleted and is no longer accessible') request.user.message_set.create(message=error_message) return HttpResponseRedirect(reverse('question', kwargs={'id': id})) except exceptions.AnswerHidden, error: request.user.message_set.create(message=unicode(error)) #use reverse function here because question is not yet loaded return HttpResponseRedirect(reverse('question', kwargs={'id': id})) except exceptions.QuestionHidden, error: request.user.message_set.create(message=unicode(error)) return HttpResponseRedirect(reverse('index'))
def question_print(request, id):#refactor - long subroutine. print question body, answers and comments """view that displays body of the question and all answers to it in print format """ #todo: fix inheritance of sort method from questions default_sort_method = request.session.get('questions_sort_method', 'votes') form = ShowQuestionForm(request.GET, default_sort_method) form.full_clean()#always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] is_permalink = form.cleaned_data['is_permalink'] answer_sort_method = form.cleaned_data['answer_sort_method'] #load question and maybe refuse showing deleted question try: question = get_object_or_404(models.Question, id=id) question.assert_is_visible_to(request.user) except exceptions.QuestionHidden, error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index'))
def question(request, id): # refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it """ # todo: fix inheritance of sort method from questions default_sort_method = request.session.get("questions_sort_method", "votes") form = ShowQuestionForm(request.GET, default_sort_method) form.full_clean() # always valid show_answer = form.cleaned_data["show_answer"] show_comment = form.cleaned_data["show_comment"] show_page = form.cleaned_data["show_page"] is_permalink = form.cleaned_data["is_permalink"] answer_sort_method = form.cleaned_data["answer_sort_method"] # resolve comment and answer permalinks # they go first because in theory both can be moved to another question # this block "returns" show_post and assigns actual comment and answer # to show_comment and show_answer variables # in the case if the permalinked items or their parents are gone - redirect # redirect also happens if id of the object's origin post != requested id show_post = None # used for permalinks if show_comment is not None: # comments try: show_comment = models.Comment.objects.get(id=show_comment) if str(show_comment.get_origin_post().id) != id: return HttpResponseRedirect(show_comment.get_absolute_url()) show_post = show_comment.content_object show_comment.assert_is_visible_to(request.user) except models.Comment.DoesNotExist: error_message = _("Sorry, the comment you are looking for has been " "deleted and is no longer accessible") request.user.message_set.create(message=error_message) return HttpResponseRedirect(reverse("question", kwargs={"id": id})) except exceptions.AnswerHidden, error: request.user.message_set.create(message=unicode(error)) # use reverse function here because question is not yet loaded return HttpResponseRedirect(reverse("question", kwargs={"id": id})) except exceptions.QuestionHidden, error: request.user.message_set.create(message=unicode(error)) return HttpResponseRedirect(reverse("index"))
def question(request, id):#refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it todo: convert this view into class """ #process url parameters #todo: fix inheritance of sort method from questions #before = timezone.now() form = ShowQuestionForm(request.REQUEST) form.full_clean()#always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] answer_sort_method = form.cleaned_data['answer_sort_method'] #load question and maybe refuse showing deleted question #if the question does not exist - try mapping to old questions #and and if it is not found again - then give up try: question_post = models.Post.objects.filter( post_type = 'question', id = id ).select_related('thread')[0] except IndexError: # Handle URL mapping - from old Q/A/C/ URLs to the new one try: question_post = models.Post.objects.filter( post_type='question', old_question_id = id ).select_related('thread')[0] except IndexError: raise Http404 if show_answer: try: old_answer = models.Post.objects.get_answers().get(old_answer_id=show_answer) except models.Post.DoesNotExist: pass else: return HttpResponseRedirect(old_answer.get_absolute_url()) elif show_comment: try: old_comment = models.Post.objects.get_comments().get(old_comment_id=show_comment) except models.Post.DoesNotExist: pass else: return HttpResponseRedirect(old_comment.get_absolute_url()) if show_comment or show_answer: try: show_post = models.Post.objects.get(pk=(show_comment or show_answer)) except models.Post.DoesNotExist: #missing target post will be handled later pass else: if (show_comment and not show_post.is_comment()) \ or (show_answer and not show_post.is_answer()): return HttpResponseRedirect(show_post.get_absolute_url()) try: question_post.assert_is_visible_to(request.user) except exceptions.QuestionHidden as error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index')) #redirect if slug in the url is wrong if request.path.split('/')[-2] != question_post.slug: logging.debug('no slug match!') lang = translation.get_language() question_url = question_post.get_absolute_url(language=lang) if request.GET: question_url += u'?' + urllib.urlencode(request.GET) return HttpResponseRedirect(question_url) #resolve comment and answer permalinks #they go first because in theory both can be moved to another question #this block "returns" show_post and assigns actual comment and answer #to show_comment and show_answer variables #in the case if the permalinked items or their parents are gone - redirect #redirect also happens if id of the object's origin post != requested id show_post = None #used for permalinks if show_comment: #if url calls for display of a specific comment, #check that comment exists, that it belongs to #the current question #if it is an answer comment and the answer is hidden - #redirect to the default view of the question #if the question is hidden - redirect to the main page #in addition - if url points to a comment and the comment #is for the answer - we need the answer object try: show_comment = models.Post.objects.get_comments().get(id=show_comment) except models.Post.DoesNotExist: error_message = _( 'Sorry, the comment you are looking for has been ' 'deleted and is no longer accessible' ) request.user.message_set.create(message = error_message) return HttpResponseRedirect(question_post.thread.get_absolute_url()) if str(show_comment.thread._question_post().id) != str(id): return HttpResponseRedirect(show_comment.get_absolute_url()) show_post = show_comment.parent try: show_comment.assert_is_visible_to(request.user) except exceptions.AnswerHidden as error: request.user.message_set.create(message = unicode(error)) #use reverse function here because question is not yet loaded return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) except exceptions.QuestionHidden as error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index')) elif show_answer: #if the url calls to view a particular answer to #question - we must check whether the question exists #whether answer is actually corresponding to the current question #and that the visitor is allowed to see it show_post = get_object_or_404(models.Post, post_type='answer', id=show_answer) if str(show_post.thread._question_post().id) != str(id): return HttpResponseRedirect(show_post.get_absolute_url()) try: show_post.assert_is_visible_to(request.user) except django_exceptions.PermissionDenied as error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) thread = question_post.thread if askbot.get_lang_mode() == 'url-lang': request_lang = translation.get_language() if request_lang != thread.language_code: template = get_template('question/lang_switch_message.html') message = template.render(Context({ 'post_lang': get_language_name(thread.language_code), 'request_lang': get_language_name(request_lang), 'home_url': reverse_i18n(request_lang, 'questions') })) request.user.message_set.create(message=message) return HttpResponseRedirect(thread.get_absolute_url()) logging.debug('answer_sort_method=' + unicode(answer_sort_method)) #load answers and post id's->athor_id mapping #posts are pre-stuffed with the correctly ordered comments question_post, answers, post_to_author, published_answer_ids = thread.get_post_data_for_question_view( sort_method=answer_sort_method, user=request.user ) user_votes = {} user_post_id_list = list() #todo: cache this query set, but again takes only 3ms! if request.user.is_authenticated(): user_votes = Vote.objects.filter( user=request.user, voted_post__id__in = post_to_author.keys() ).values_list('voted_post_id', 'vote') user_votes = dict(user_votes) #we can avoid making this query by iterating through #already loaded posts user_post_id_list = [ post_id for post_id in post_to_author if post_to_author[post_id] == request.user.id ] #resolve page number and comment number for permalinks show_comment_position = None if show_comment: show_page = show_comment.get_page_number(answer_posts=answers) show_comment_position = show_comment.get_order_number() elif show_answer: show_page = show_post.get_page_number(answer_posts=answers) objects_list = Paginator(answers, const.ANSWERS_PAGE_SIZE) if show_page > objects_list.num_pages: return HttpResponseRedirect(question_post.get_absolute_url()) page_objects = objects_list.page(show_page) #count visits signals.question_visited.send(None, request=request, question=question_post, ) paginator_data = { 'is_paginated' : (objects_list.count > const.ANSWERS_PAGE_SIZE), 'pages': objects_list.num_pages, 'current_page_number': show_page, 'page_object': page_objects, 'base_url' : request.path + '?sort=%s&' % answer_sort_method, } paginator_context = functions.setup_paginator(paginator_data) #todo: maybe consolidate all activity in the thread #for the user into just one query? favorited = thread.has_favorite_by_user(request.user) is_cacheable = True if show_page != 1: is_cacheable = False elif show_comment_position > askbot_settings.MAX_COMMENTS_TO_SHOW: is_cacheable = False #maybe load draft initial = {} if request.user.is_authenticated(): #todo: refactor into methor on thread drafts = models.DraftAnswer.objects.filter( author=request.user, thread=thread ) if drafts.count() > 0: initial['text'] = drafts[0].get_text() custom_answer_form_path = django_settings.ASKBOT_NEW_ANSWER_FORM if custom_answer_form_path: answer_form_class = load_module(custom_answer_form_path) else: answer_form_class = AnswerForm answer_form = answer_form_class(initial=initial, user=request.user) user_can_post_comment = ( request.user.is_authenticated() \ and request.user.can_post_comment(question_post) ) new_answer_allowed = True previous_answer = None if request.user.is_authenticated(): if askbot_settings.LIMIT_ONE_ANSWER_PER_USER: for answer in answers: if answer.author_id == request.user.pk: new_answer_allowed = False previous_answer = answer break if request.user.is_authenticated() and askbot_settings.GROUPS_ENABLED: group_read_only = request.user.is_read_only() else: group_read_only = False #session variable added so that the session is #not empty and is not autodeleted, otherwise anonymous #answer posting is impossible request.session['askbot_write_intent'] = True data = { 'active_tab': 'questions', 'answer' : answer_form, 'answers' : page_objects.object_list, 'answer_count': thread.get_answer_count(request.user), 'blank_comment': MockPost(post_type='comment', author=request.user),#data for the js comment template 'category_tree_data': askbot_settings.CATEGORY_TREE, 'favorited' : favorited, 'group_read_only': group_read_only, 'is_cacheable': False,#is_cacheable, #temporary, until invalidation fix 'language_code': translation.get_language(), 'long_time': const.LONG_TIME,#"forever" caching 'new_answer_allowed': new_answer_allowed, 'oldest_answer_id': thread.get_oldest_answer_id(request.user), 'page_class': 'question-page', 'paginator_context' : paginator_context, 'previous_answer': previous_answer, 'published_answer_ids': published_answer_ids, 'question' : question_post, 'show_comment': show_comment, 'show_comment_position': show_comment_position, 'show_post': show_post, 'similar_threads' : thread.get_similar_threads(), 'tab_id' : answer_sort_method, 'thread': thread, 'thread_is_moderated': thread.is_moderated(), 'user_is_thread_moderator': thread.has_moderator(request.user), 'user_votes': user_votes, 'user_post_id_list': user_post_id_list, 'user_can_post_comment': user_can_post_comment,#in general } #shared with ... if askbot_settings.GROUPS_ENABLED: data['sharing_info'] = thread.get_sharing_info() data.update(context.get_for_tag_editor()) extra = context.get_extra('ASKBOT_QUESTION_PAGE_EXTRA_CONTEXT', request, data) data.update(extra) return render(request, 'question.html', data)
def question(request, id):#refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it """ #process url parameters #todo: fix inheritance of sort method from questions default_sort_method = request.session.get('questions_sort_method', 'votes') form = ShowQuestionForm(request.GET, default_sort_method) form.full_clean()#always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] answer_sort_method = form.cleaned_data['answer_sort_method'] # Handle URL mapping - from old Q/A/C/ URLs to the new one if not models.Post.objects.get_questions().filter(id=id).exists() and models.Post.objects.get_questions().filter(old_question_id=id).exists(): old_question = models.Post.objects.get_questions().get(old_question_id=id) # If we are supposed to show a specific answer or comment, then just redirect to the new URL... if show_answer: try: old_answer = models.Post.objects.get_answers().get(old_answer_id=show_answer) return HttpResponseRedirect(old_answer.get_absolute_url()) except models.Post.DoesNotExist: pass elif show_comment: try: old_comment = models.Post.objects.get_comments().get(old_comment_id=show_comment) return HttpResponseRedirect(old_comment.get_absolute_url()) except models.Post.DoesNotExist: pass # ...otherwise just patch question.id, to make URLs like this one work: /question/123#345 # This is because URL fragment (hash) (i.e. #345) is not passed to the server so we can't know which # answer user expects to see. If we made a redirect to the new question.id then that hash would be lost. # And if we just hack the question.id (and in question.html template /or its subtemplate/ we create anchors for both old and new id-s) # then everything should work as expected. id = old_question.id #resolve comment and answer permalinks #they go first because in theory both can be moved to another question #this block "returns" show_post and assigns actual comment and answer #to show_comment and show_answer variables #in the case if the permalinked items or their parents are gone - redirect #redirect also happens if id of the object's origin post != requested id show_post = None #used for permalinks if show_comment: #if url calls for display of a specific comment, #check that comment exists, that it belongs to #the current question #if it is an answer comment and the answer is hidden - #redirect to the default view of the question #if the question is hidden - redirect to the main page #in addition - if url points to a comment and the comment #is for the answer - we need the answer object try: show_comment = models.Post.objects.get_comments().get(id=show_comment) except models.Post.DoesNotExist: error_message = _( 'Sorry, the comment you are looking for has been ' 'deleted and is no longer accessible' ) request.user.message_set.create(message = error_message) return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) if str(show_comment.thread._question_post().id) != str(id): return HttpResponseRedirect(show_comment.get_absolute_url()) show_post = show_comment.parent try: show_comment.assert_is_visible_to(request.user) except exceptions.AnswerHidden, error: request.user.message_set.create(message = unicode(error)) #use reverse function here because question is not yet loaded return HttpResponseRedirect(reverse('question', kwargs = {'id': id})) except exceptions.QuestionHidden, error: request.user.message_set.create(message = unicode(error)) return HttpResponseRedirect(reverse('index'))
def question(request, id): # refactor - long subroutine. display question body, answers and comments """view that displays body of the question and all answers to it TODO: convert this view into class """ # process url parameters # TODO: fix inheritance of sort method from questions form = ShowQuestionForm(dict(tuple(request.POST.items()) + tuple(request.GET.items()))) form.full_clean() # always valid show_answer = form.cleaned_data['show_answer'] show_comment = form.cleaned_data['show_comment'] show_page = form.cleaned_data['show_page'] answer_sort_method = form.cleaned_data['answer_sort_method'] # load question and maybe refuse showing deleted question # if the question does not exist - try mapping to old questions # and and if it is not found again - then give up qs = Post.objects.filter(post_type='question').select_related('thread') question_post = qs.filter(id=id).first() if question_post is None: # Handle URL mapping - from old Q/A/C/ URLs to the new one question_post = qs.filter(old_question_id=id).first() if question_post is None: raise Http404 if show_answer: try: old_answer = Post.objects.get_answers().get(old_answer_id=show_answer) except Post.DoesNotExist: pass else: return redirect(old_answer) elif show_comment: try: old_comment = Post.objects.get_comments().get(old_comment_id=show_comment) except Post.DoesNotExist: pass else: return redirect(old_comment) if show_comment or show_answer: try: show_post = Post.objects.get(pk=(show_comment or show_answer)) except Post.DoesNotExist: # missing target post will be handled later pass else: if (show_comment and not show_post.is_comment()) or \ (show_answer and not show_post.is_answer()): return redirect(show_post) try: question_post.assert_is_visible_to(request.user) except exceptions.QuestionHidden as error: traceback.print_exc() # request.user.message_set.create(message=force_text(error)) django_messages.info(request, force_text(error)) return redirect('index') # redirect if slug in the url is wrong if request.path.split('/')[-2] != question_post.slug: logging.debug('no slug match!') lang = translation.get_language() question_url = question_post.get_absolute_url(language=lang) if request.GET: question_url += '?' + urlencode(request.GET) return redirect(question_url) # resolve comment and answer permalinks # they go first because in theory both can be moved to another question # this block "returns" show_post and assigns actual comment and answer # to show_comment and show_answer variables # in the case if the permalinked items or their parents are gone - redirect # redirect also happens if id of the object's origin post != requested id show_post = None # used for permalinks if show_comment: # if url calls for display of a specific comment, # check that comment exists, that it belongs to # the current question # if it is an answer comment and the answer is hidden - # redirect to the default view of the question # if the question is hidden - redirect to the main page # in addition - if url points to a comment and the comment # is for the answer - we need the answer object try: show_comment = Post.objects.get_comments().get(id=show_comment) except Post.DoesNotExist as e: traceback.print_exc() error_message = _( 'Sorry, the comment you are looking for has been ' 'deleted and is no longer accessible' ) # request.user.message_set.create(message=error_message) django_messages.info(request, error_message) return redirect(question_post.thread) if str(show_comment.thread._question_post().id) != str(id): return redirect(show_comment) show_post = show_comment.parent try: show_comment.assert_is_visible_to(request.user) except exceptions.AnswerHidden as e: traceback.print_exc() # request.user.message_set.create(message=force_text(e)) django_messages.info(request, force_text(e)) # use reverse function here because question is not yet loaded return redirect('question', id=id) except exceptions.QuestionHidden as e: traceback.print_exc() # request.user.message_set.create(message=force_text(e)) django_messages.info(request, force_text(e)) return redirect('index') elif show_answer: # if the url calls to view a particular answer to # question - we must check whether the question exists # whether answer is actually corresponding to the current question # and that the visitor is allowed to see it show_post = get_object_or_404(Post, post_type='answer', id=show_answer) if str(show_post.thread._question_post().id) != str(id): return redirect(show_post) try: show_post.assert_is_visible_to(request.user) except django_exceptions.PermissionDenied as e: traceback.print_exc() # request.user.message_set.create(message=force_text(e)) django_messages.info(request, force_text(e)) return redirect('question', id=id) thread = question_post.thread logging.debug('answer_sort_method=' + force_text(answer_sort_method)) # load answers and post id's->athor_id mapping # posts are pre-stuffed with the correctly ordered comments question_post, answers, post_to_author, published_answer_ids = thread.get_post_data_for_question_view( sort_method=answer_sort_method, user=request.user) user_votes = {} user_post_id_list = list() # TODO: cache this query set, but again takes only 3ms! if request.user.is_authenticated(): user_votes = Vote.objects.\ filter(user=request.user, voted_post__id__in=post_to_author.keys()).\ values_list('voted_post_id', 'vote') user_votes = dict(user_votes) # we can avoid making this query by iterating through # already loaded posts user_post_id_list = [ post_id for post_id in post_to_author if post_to_author[post_id] == request.user.id ] # resolve page number and comment number for permalinks show_comment_position = None if show_comment: show_page = show_comment.get_page_number(answer_posts=answers) show_comment_position = show_comment.get_order_number() elif show_answer: show_page = show_post.get_page_number(answer_posts=answers) objects_list = Paginator(answers, const.ANSWERS_PAGE_SIZE) if show_page > objects_list.num_pages: return redirect(question_post) page_objects = objects_list.page(show_page) # count visits signals.question_visited.send(None, request=request, question=question_post) paginator_data = { 'is_paginated': (objects_list.count > const.ANSWERS_PAGE_SIZE), 'pages': objects_list.num_pages, 'current_page_number': show_page, 'page_object': page_objects, 'base_url': request.path + '?sort=%s&' % answer_sort_method, } paginator_context = functions.setup_paginator(paginator_data) # TODO: maybe consolidate all activity in the thread # for the user into just one query? favorited = thread.has_favorite_by_user(request.user) is_cacheable = True if show_page != 1: is_cacheable = False elif (show_comment_position or 0) > askbot_settings.MAX_COMMENTS_TO_SHOW: is_cacheable = False # maybe load draft initial = {} if request.user.is_authenticated(): # TODO: refactor into methor on thread drafts = DraftAnswer.objects.filter(author=request.user, thread=thread) if drafts.count() > 0: initial['text'] = drafts[0].text custom_answer_form_path = getattr(django_settings, 'ASKBOT_NEW_ANSWER_FORM', None) if custom_answer_form_path: answer_form_class = load_module(custom_answer_form_path) else: answer_form_class = AnswerForm answer_form = answer_form_class(initial=initial, user=request.user) user_can_post_comment = (request.user.is_authenticated() and request.user.can_post_comment(question_post)) new_answer_allowed = True previous_answer = None if request.user.is_authenticated(): if askbot_settings.LIMIT_ONE_ANSWER_PER_USER: for answer in answers: if answer.author_id == request.user.pk: new_answer_allowed = False previous_answer = answer break if request.user.is_authenticated() and askbot_settings.GROUPS_ENABLED: group_read_only = request.user.is_read_only() else: group_read_only = False data = { 'active_tab': 'questions', 'answer': answer_form, 'answers': page_objects.object_list, 'answer_count': thread.get_answer_count(request.user), 'blank_comment': MockPost(post_type='comment', author=request.user), # data for the js comment template 'category_tree_data': askbot_settings.CATEGORY_TREE, 'editor_is_unfolded': answer_form.has_data(), 'favorited': favorited, 'group_read_only': group_read_only, 'is_cacheable': False, # is_cacheable, # temporary, until invalidation fix 'language_code': translation.get_language(), 'long_time': const.LONG_TIME, # "forever" caching 'new_answer_allowed': new_answer_allowed, 'oldest_answer_id': thread.get_oldest_answer_id(request.user), 'page_class': 'question-page', 'paginator_context': paginator_context, 'previous_answer': previous_answer, 'published_answer_ids': published_answer_ids, 'question': question_post, 'show_comment': show_comment, 'show_comment_position': show_comment_position, 'show_post': show_post, 'similar_threads': thread.get_similar_threads(), 'tab_id': answer_sort_method, 'thread': thread, 'thread_is_moderated': thread.is_moderated(), 'user_is_thread_moderator': thread.has_moderator(request.user), 'user_votes': user_votes, 'user_post_id_list': user_post_id_list, 'user_can_post_comment': user_can_post_comment, # in general } # shared with ... if askbot_settings.GROUPS_ENABLED: data['sharing_info'] = thread.get_sharing_info() data.update(context.get_for_tag_editor()) extra = context.get_extra('ASKBOT_QUESTION_PAGE_EXTRA_CONTEXT', request, data) data.update(extra) return render(request, 'question.jinja', data)