models: Use unlimited .select_related() for Stream and DefaultStream.

Previously, these accesses used e.g. .select_related("realm"), which
was the only foreign key on the Stream model.  Since the intent in
these code paths is to attach the related models for efficient access,
we should just do that for all related models, including Recipient.
This commit is contained in:
Tim Abbott 2019-12-12 12:13:07 -08:00
parent 9a42a83e15
commit f3c224058f
2 changed files with 6 additions and 7 deletions

View File

@ -1491,7 +1491,7 @@ def do_send_messages(messages_maybe_none: Sequence[Optional[MutableMapping[str,
# messages are only associated to their subscribed users. # messages are only associated to their subscribed users.
if message['stream'] is None: if message['stream'] is None:
stream_id = message['message'].recipient.type_id stream_id = message['message'].recipient.type_id
message['stream'] = Stream.objects.select_related("realm").get(id=stream_id) message['stream'] = Stream.objects.select_related().get(id=stream_id)
assert message['stream'] is not None # assert needed because stubs for django are missing assert message['stream'] is not None # assert needed because stubs for django are missing
if message['stream'].is_public(): if message['stream'].is_public():
event['realm_id'] = message['stream'].realm_id event['realm_id'] = message['stream'].realm_id
@ -3947,8 +3947,7 @@ def do_remove_default_stream_group(realm: Realm, group: DefaultStreamGroup) -> N
def get_default_streams_for_realm(realm_id: int) -> List[Stream]: def get_default_streams_for_realm(realm_id: int) -> List[Stream]:
return [default.stream for default in return [default.stream for default in
DefaultStream.objects.select_related("stream", "stream__realm").filter( DefaultStream.objects.select_related().filter(realm_id=realm_id)]
realm_id=realm_id)]
def get_default_subs(user_profile: UserProfile) -> List[Stream]: def get_default_subs(user_profile: UserProfile) -> List[Stream]:
# Right now default streams are realm-wide. This wrapper gives us flexibility # Right now default streams are realm-wide. This wrapper gives us flexibility

View File

@ -1459,7 +1459,7 @@ def get_client_remote_cache(name: str) -> Client:
@cache_with_key(get_stream_cache_key, timeout=3600*24*7) @cache_with_key(get_stream_cache_key, timeout=3600*24*7)
def get_realm_stream(stream_name: str, realm_id: int) -> Stream: def get_realm_stream(stream_name: str, realm_id: int) -> Stream:
return Stream.objects.select_related("realm").get( return Stream.objects.select_related().get(
name__iexact=stream_name.strip(), realm_id=realm_id) name__iexact=stream_name.strip(), realm_id=realm_id)
def stream_name_in_use(stream_name: str, realm_id: int) -> bool: def stream_name_in_use(stream_name: str, realm_id: int) -> bool:
@ -1493,14 +1493,14 @@ def bulk_get_streams(realm: Realm, stream_names: STREAM_NAMES) -> Dict[str, Any]
# #
# This should be just # This should be just
# #
# Stream.objects.select_related("realm").filter(name__iexact__in=stream_names, # Stream.objects.select_related().filter(name__iexact__in=stream_names,
# realm_id=realm_id) # realm_id=realm_id)
# #
# But chaining __in and __iexact doesn't work with Django's # But chaining __in and __iexact doesn't work with Django's
# ORM, so we have the following hack to construct the relevant where clause # ORM, so we have the following hack to construct the relevant where clause
upper_list = ", ".join(["UPPER(%s)"] * len(stream_names)) upper_list = ", ".join(["UPPER(%s)"] * len(stream_names))
where_clause = "UPPER(zerver_stream.name::text) IN (%s)" % (upper_list,) where_clause = "UPPER(zerver_stream.name::text) IN (%s)" % (upper_list,)
return get_active_streams(realm.id).select_related("realm").extra( return get_active_streams(realm.id).select_related().extra(
where=[where_clause], where=[where_clause],
params=stream_names) params=stream_names)