def action_merge(self, request, threads): if len(threads) == 1: message = _("You have to select at least two threads to merge.") raise moderation.ModerationError(message) form = MergeThreadsForm() if 'submit' in request.POST: form = MergeThreadsForm(request.POST) if form.is_valid(): with atomic(): merged_thread = Thread() merged_thread.forum = self.forum merged_thread.set_title( form.cleaned_data['merged_thread_title']) merged_thread.starter_name = "-" merged_thread.starter_slug = "-" merged_thread.last_poster_name = "-" merged_thread.last_poster_slug = "-" merged_thread.started_on = timezone.now() merged_thread.last_post_on = timezone.now() merged_thread.is_pinned = max(t.is_pinned for t in threads) merged_thread.is_closed = max(t.is_closed for t in threads) merged_thread.save() for thread in threads: moderation.merge_thread( request.user, merged_thread, thread) merged_thread.synchronize() merged_thread.save() self.forum.lock() self.forum.synchronize() self.forum.save() changed_threads = len(threads) message = ungettext( '%(changed)d thread was merged into "%(thread)s".', '%(changed)d threads were merged into "%(thread)s".', changed_threads) messages.success(request, message % { 'changed': changed_threads, 'thread': merged_thread.title }) return None # trigger threads list refresh if request.is_ajax(): template = self.merge_threads_modal_template else: template = self.merge_threads_full_template return render(request, template, { 'form': form, 'forum': self.forum, 'path': get_forum_path(self.forum), 'threads': threads })
def thread_merge_endpoint(request, thread, viewmodel): allow_merge_thread(request.user, thread) serializer = MergeThreadSerializer( data=request.data, context={ 'request': request, 'thread': thread, 'viewmodel': viewmodel, }, ) serializer.is_valid(raise_exception=True) # merge conflict other_thread = serializer.validated_data['other_thread'] best_answer = serializer.validated_data.get('best_answer') if 'best_answer' in serializer.merge_conflict and not best_answer: other_thread.clear_best_answer() if best_answer and best_answer != other_thread: other_thread.best_answer_id = thread.best_answer_id other_thread.best_answer_is_protected = thread.best_answer_is_protected other_thread.best_answer_marked_on = thread.best_answer_marked_on other_thread.best_answer_marked_by_id = thread.best_answer_marked_by_id other_thread.best_answer_marked_by_name = thread.best_answer_marked_by_name other_thread.best_answer_marked_by_slug = thread.best_answer_marked_by_slug poll = serializer.validated_data.get('poll') if 'poll' in serializer.merge_conflict: if poll and poll.thread_id != other_thread.id: other_thread.poll.delete() poll.move(other_thread) elif not poll: other_thread.poll.delete() elif poll: poll.move(other_thread) # merge thread contents moderation.merge_thread(request, other_thread, thread) other_thread.synchronize() other_thread.save() other_thread.category.synchronize() other_thread.category.save() if thread.category != other_thread.category: thread.category.synchronize() thread.category.save() return Response({ 'id': other_thread.pk, 'title': other_thread.title, 'url': other_thread.get_absolute_url(), })
def test_thread_merged_event_renders(self): """merged thread event renders""" other_thread = testutils.post_thread(category=self.category) moderation.merge_thread(MockRequest(self.user), self.thread, other_thread) event = self.thread.post_set.filter(is_event=True)[0] self.assertEqual(event.event_type, 'merged') # event renders response = self.client.get(self.thread.get_absolute_url()) self.assertContains(response, event.get_absolute_url()) self.assertContains(response, "thread has been merged into this thread")