use outer join instead #331

This commit is contained in:
rimu 2024-09-30 13:49:06 +13:00
parent 3ad1071e01
commit bba8687567
6 changed files with 16 additions and 31 deletions

View file

@ -29,7 +29,7 @@ from app.inoculation import inoculation
from app.models import User, Community, CommunityMember, CommunityJoinRequest, CommunityBan, Post, \ from app.models import User, Community, CommunityMember, CommunityJoinRequest, CommunityBan, Post, \
File, PostVote, utcnow, Report, Notification, InstanceBlock, ActivityPubLog, Topic, Conversation, PostReply, \ File, PostVote, utcnow, Report, Notification, InstanceBlock, ActivityPubLog, Topic, Conversation, PostReply, \
NotificationSubscription, UserFollower, Instance, Language, Poll, PollChoice, ModLog, CommunityWikiPage, \ NotificationSubscription, UserFollower, Instance, Language, Poll, PollChoice, ModLog, CommunityWikiPage, \
CommunityWikiPageRevision CommunityWikiPageRevision, read_posts
from app.community import bp from app.community import bp
from app.user.utils import search_for_user from app.user.utils import search_for_user
from app.utils import get_setting, render_template, allowlist_html, markdown_to_html, validation_required, \ from app.utils import get_setting, render_template, allowlist_html, markdown_to_html, validation_required, \
@ -229,12 +229,8 @@ def show_community(community: Community):
if current_user.hide_nsfw == 1: if current_user.hide_nsfw == 1:
posts = posts.filter(Post.nsfw == False) posts = posts.filter(Post.nsfw == False)
if current_user.hide_read_posts: if current_user.hide_read_posts:
cu_rp = current_user.read_post.all() posts = posts.outerjoin(read_posts, (Post.id == read_posts.c.read_post_id) & (read_posts.c.user_id == current_user.id))
cu_rp_ids = [] posts = posts.filter(read_posts.c.read_post_id.is_(None)) # Filter where there is no corresponding read post for the current user
for p in cu_rp:
cu_rp_ids.append(p.id)
for p_id in cu_rp_ids:
posts = posts.filter(Post.id != p_id)
content_filters = user_filters_posts(current_user.id) content_filters = user_filters_posts(current_user.id)
posts = posts.filter(Post.deleted == False) posts = posts.filter(Post.deleted == False)

View file

@ -6,7 +6,7 @@ from flask_babel import _
from app import db, constants, cache from app import db, constants, cache
from app.inoculation import inoculation from app.inoculation import inoculation
from app.models import Post, Domain, Community, DomainBlock from app.models import Post, Domain, Community, DomainBlock, read_posts
from app.domain import bp from app.domain import bp
from app.utils import render_template, permission_required, joined_communities, moderating_communities, \ from app.utils import render_template, permission_required, joined_communities, moderating_communities, \
user_filters_posts, blocked_domains, blocked_instances, menu_topics user_filters_posts, blocked_domains, blocked_instances, menu_topics
@ -41,12 +41,8 @@ def show_domain(domain_id):
# don't show posts a user has already interacted with # don't show posts a user has already interacted with
if current_user.hide_read_posts: if current_user.hide_read_posts:
cu_rp = current_user.read_post.all() posts = posts.outerjoin(read_posts, (Post.id == read_posts.c.read_post_id) & (read_posts.c.user_id == current_user.id))
cu_rp_ids = [] posts = posts.filter(read_posts.c.read_post_id.is_(None)) # Filter where there is no corresponding read post for the current user
for p in cu_rp:
cu_rp_ids.append(p.id)
for p_id in cu_rp_ids:
posts = posts.filter(Post.id != p_id)
# pagination # pagination
posts = posts.paginate(page=page, per_page=100, error_out=False) posts = posts.paginate(page=page, per_page=100, error_out=False)

View file

@ -24,7 +24,7 @@ from app.utils import render_template, get_setting, request_etag_matches, return
blocked_instances, communities_banned_from, topic_tree, recently_upvoted_posts, recently_downvoted_posts, \ blocked_instances, communities_banned_from, topic_tree, recently_upvoted_posts, recently_downvoted_posts, \
blocked_users, menu_topics, languages_for_form, blocked_communities, get_request blocked_users, menu_topics, languages_for_form, blocked_communities, get_request
from app.models import Community, CommunityMember, Post, Site, User, utcnow, Topic, Instance, \ from app.models import Community, CommunityMember, Post, Site, User, utcnow, Topic, Instance, \
Notification, Language, community_language, ModLog Notification, Language, community_language, ModLog, read_posts
@bp.route('/', methods=['HEAD', 'GET', 'POST']) @bp.route('/', methods=['HEAD', 'GET', 'POST'])
@ -72,12 +72,8 @@ def home_page(sort, view_filter):
if current_user.hide_nsfw == 1: if current_user.hide_nsfw == 1:
posts = posts.filter(Post.nsfw == False) posts = posts.filter(Post.nsfw == False)
if current_user.hide_read_posts: if current_user.hide_read_posts:
cu_rp = current_user.read_post.all() posts = posts.outerjoin(read_posts, (Post.id == read_posts.c.read_post_id) & (read_posts.c.user_id == current_user.id))
cu_rp_ids = [] posts = posts.filter(read_posts.c.read_post_id.is_(None)) # Filter where there is no corresponding read post for the current user
for p in cu_rp:
cu_rp_ids.append(p.id)
for p_id in cu_rp_ids:
posts = posts.filter(Post.id != p_id)
domains_ids = blocked_domains(current_user.id) domains_ids = blocked_domains(current_user.id)
if domains_ids: if domains_ids:

View file

@ -617,9 +617,10 @@ user_role = db.Table('user_role',
read_posts = db.Table('read_posts', read_posts = db.Table('read_posts',
db.Column('user_id', db.Integer, db.ForeignKey('user.id'), index=True), db.Column('user_id', db.Integer, db.ForeignKey('user.id'), index=True),
db.Column('read_post_id', db.Integer, db.ForeignKey('post.id'), index=True), db.Column('read_post_id', db.Integer, db.ForeignKey('post.id'), index=True),
db.Column('interacted_at', db.DateTime, index=True, default=utcnow) # this is when the content is interacte with db.Column('interacted_at', db.DateTime, index=True, default=utcnow) # this is when the content is interacted with
) )
class User(UserMixin, db.Model): class User(UserMixin, db.Model):
query_class = FullTextSearchQuery query_class = FullTextSearchQuery
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)

View file

@ -12,10 +12,10 @@
<ol class="breadcrumb"> <ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/">{{ _('Home') }}</a></li> <li class="breadcrumb-item"><a href="/">{{ _('Home') }}</a></li>
<li class="breadcrumb-item"><a href="/u/{{ user.link() }}">{{ user.display_name() }}</a></li> <li class="breadcrumb-item"><a href="/u/{{ user.link() }}">{{ user.display_name() }}</a></li>
<li class="breadcrumb-item active">{{ _('Read Posts') }}</li> <li class="breadcrumb-item active">{{ _('Read posts') }}</li>
</ol> </ol>
</nav> </nav>
<h1>{{ _('Read Posts') }}</h1> <h1>{{ _('Read posts') }}</h1>
<div class="post_list"> <div class="post_list">
{% for post in posts.items -%} {% for post in posts.items -%}
{% include 'post/_post_teaser.html' %} {% include 'post/_post_teaser.html' %}

View file

@ -14,7 +14,7 @@ from app.constants import SUBSCRIPTION_NONMEMBER, SUBSCRIPTION_OWNER, SUBSCRIPTI
POST_TYPE_LINK, POST_TYPE_VIDEO, NOTIF_TOPIC POST_TYPE_LINK, POST_TYPE_VIDEO, NOTIF_TOPIC
from app.inoculation import inoculation from app.inoculation import inoculation
from app.models import Topic, Community, Post, utcnow, CommunityMember, CommunityJoinRequest, User, \ from app.models import Topic, Community, Post, utcnow, CommunityMember, CommunityJoinRequest, User, \
NotificationSubscription NotificationSubscription, read_posts
from app.topic import bp from app.topic import bp
from app.email import send_email, send_topic_suggestion from app.email import send_email, send_topic_suggestion
from app import db, celery, cache from app import db, celery, cache
@ -66,12 +66,8 @@ def show_topic(topic_path):
if current_user.hide_nsfw == 1: if current_user.hide_nsfw == 1:
posts = posts.filter(Post.nsfw == False) posts = posts.filter(Post.nsfw == False)
if current_user.hide_read_posts: if current_user.hide_read_posts:
cu_rp = current_user.read_post.all() posts = posts.outerjoin(read_posts, (Post.id == read_posts.c.read_post_id) & (read_posts.c.user_id == current_user.id))
cu_rp_ids = [] posts = posts.filter(read_posts.c.read_post_id.is_(None)) # Filter where there is no corresponding read post for the current user
for p in cu_rp:
cu_rp_ids.append(p.id)
for p_id in cu_rp_ids:
posts = posts.filter(Post.id != p_id)
posts = posts.filter(Post.deleted == False) posts = posts.filter(Post.deleted == False)
content_filters = user_filters_posts(current_user.id) content_filters = user_filters_posts(current_user.id)