bgneal@147: """ bgneal@147: This module contains misc. utility functions for forum management. bgneal@147: """ bgneal@147: from forums.models import Post, Topic, Forum, ForumLastVisit, TopicLastVisit bgneal@147: bgneal@147: bgneal@147: def delete_user_posts(user): bgneal@147: """ bgneal@147: This function deletes all the posts for a given user. bgneal@147: It also cleans up any last visit database records for the user. bgneal@147: This function adjusts the last post foreign keys before deleting bgneal@147: the posts to avoid the cascading delete behavior. bgneal@147: """ bgneal@147: posts = Post.objects.filter(user=user).select_related() bgneal@147: bgneal@147: # build a set of topics and forums affected by the post deletions bgneal@147: bgneal@147: topics = set(post.topic for post in posts) bgneal@147: forums = set(topic.forum for topic in topics) bgneal@147: bgneal@147: post_ids = [post.pk for post in posts] bgneal@147: pending_delete = [] bgneal@147: bgneal@147: for topic in topics: bgneal@147: if topic.last_post.pk in post_ids: bgneal@147: topic_posts = Post.objects.filter(topic=topic).exclude( bgneal@147: pk__in=post_ids) bgneal@147: topic.post_count = topic_posts.count() bgneal@147: if topic.post_count > 0: bgneal@147: topic.last_post = topic_posts.latest() bgneal@147: topic.update_date = topic.last_post.creation_date bgneal@147: topic.save() bgneal@147: else: bgneal@147: # Topic should be deleted, it has no posts; bgneal@147: # We can't delete it now as it could cascade and take out a bgneal@147: # forum. Remember it for later deletion. bgneal@147: pending_delete.append(topic) bgneal@147: bgneal@147: for forum in forums: bgneal@147: if forum.last_post.pk in post_ids: bgneal@147: forum_posts = Post.objects.filter(topic__forum=forum).exclude( bgneal@147: pk__in=post_ids) bgneal@147: forum.post_count = forum_posts.count() bgneal@147: if forum.post_count > 0: bgneal@147: forum.last_post = forum_posts.latest() bgneal@147: else: bgneal@147: forum.last_post = None bgneal@147: forum.save() bgneal@147: bgneal@147: # Delete pending topics now because forums have just adjusted their bgneal@147: # foreign keys into Post bgneal@147: if pending_delete: bgneal@147: topic_ids = [topic.pk for topic in pending_delete] bgneal@147: Topic.objects.filter(pk__in=topic_ids).delete() bgneal@147: bgneal@147: # Topics have been deleted, re-compute topic counts for forums bgneal@147: for forum in forums: bgneal@147: forum.topic_count = Topic.objects.filter(forum=forum).count() bgneal@147: forum.save() bgneal@147: bgneal@147: # All foreign keys are accounted for, we can now delete the posts in bulk. bgneal@147: # Since some posts in our original queryset may have been deleted already, bgneal@147: # run a new query (although it may be ok) bgneal@147: Post.objects.filter(pk__in=post_ids).delete() bgneal@147: bgneal@147: # delete all the last visit records for this user bgneal@147: TopicLastVisit.objects.filter(user=user).delete() bgneal@147: ForumLastVisit.objects.filter(user=user).delete() bgneal@147: