We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Number of followers of suggested users is wrong
**Describe the bug**
Recommendations for new users to follow in my feed appear with a number of followers we have in common, but that number looks off. The user recommendation I saw said they had 306 followers I follow, but neither of us has that many followers.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to your home feed after logging in
3. Scroll down until you see a recommendation for a user to follow
4. See the weird follower count

**Expected behavior**
The number of mutual followers should be accurate 

**Screenshots**
If applicable, add screenshots to help explain your problem.

Screenshot
![409385BB-8652-4B7C-9137-5B6CDB7F0866](https://user-images.githubusercontent.com/1128631/112738864-2ca94580-8f3d-11eb-92af-a86dc7148986.jpeg)

**Smartphone (please complete the following information):**
    - Device: iPhone 11
    - OS: 
    - Browser safari
    - Version

**Additional context**



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `bookwyrm/views/helpers.py`
Content:
```
1 """ helper functions used in various views """
2 import re
3 from requests import HTTPError
4 from django.core.exceptions import FieldError
5 from django.db.models import Count, Max, Q
6 
7 from bookwyrm import activitypub, models
8 from bookwyrm.connectors import ConnectorException, get_data
9 from bookwyrm.status import create_generated_note
10 from bookwyrm.utils import regex
11 
12 
13 def get_user_from_username(viewer, username):
14     """ helper function to resolve a localname or a username to a user """
15     # raises DoesNotExist if user is now found
16     try:
17         return models.User.viewer_aware_objects(viewer).get(localname=username)
18     except models.User.DoesNotExist:
19         return models.User.viewer_aware_objects(viewer).get(username=username)
20 
21 
22 def is_api_request(request):
23     """ check whether a request is asking for html or data """
24     return "json" in request.headers.get("Accept") or request.path[-5:] == ".json"
25 
26 
27 def is_bookwyrm_request(request):
28     """ check if the request is coming from another bookwyrm instance """
29     user_agent = request.headers.get("User-Agent")
30     if user_agent is None or re.search(regex.bookwyrm_user_agent, user_agent) is None:
31         return False
32     return True
33 
34 
35 def object_visible_to_user(viewer, obj):
36     """ is a user authorized to view an object? """
37     if not obj:
38         return False
39 
40     # viewer can't see it if the object's owner blocked them
41     if viewer in obj.user.blocks.all():
42         return False
43 
44     # you can see your own posts and any public or unlisted posts
45     if viewer == obj.user or obj.privacy in ["public", "unlisted"]:
46         return True
47 
48     # you can see the followers only posts of people you follow
49     if obj.privacy == "followers" and obj.user.followers.filter(id=viewer.id).first():
50         return True
51 
52     # you can see dms you are tagged in
53     if isinstance(obj, models.Status):
54         if obj.privacy == "direct" and obj.mention_users.filter(id=viewer.id).first():
55             return True
56     return False
57 
58 
59 def privacy_filter(viewer, queryset, privacy_levels=None, following_only=False):
60     """ filter objects that have "user" and "privacy" fields """
61     privacy_levels = privacy_levels or ["public", "unlisted", "followers", "direct"]
62     # if there'd a deleted field, exclude deleted items
63     try:
64         queryset = queryset.filter(deleted=False)
65     except FieldError:
66         pass
67 
68     # exclude blocks from both directions
69     if not viewer.is_anonymous:
70         blocked = models.User.objects.filter(id__in=viewer.blocks.all()).all()
71         queryset = queryset.exclude(Q(user__in=blocked) | Q(user__blocks=viewer))
72 
73     # you can't see followers only or direct messages if you're not logged in
74     if viewer.is_anonymous:
75         privacy_levels = [p for p in privacy_levels if not p in ["followers", "direct"]]
76 
77     # filter to only privided privacy levels
78     queryset = queryset.filter(privacy__in=privacy_levels)
79 
80     # only include statuses the user follows
81     if following_only:
82         queryset = queryset.exclude(
83             ~Q(  # remove everythign except
84                 Q(user__in=viewer.following.all())
85                 | Q(user=viewer)  # user following
86                 | Q(mention_users=viewer)  # is self  # mentions user
87             ),
88         )
89     # exclude followers-only statuses the user doesn't follow
90     elif "followers" in privacy_levels:
91         queryset = queryset.exclude(
92             ~Q(  # user isn't following and it isn't their own status
93                 Q(user__in=viewer.following.all()) | Q(user=viewer)
94             ),
95             privacy="followers",  # and the status is followers only
96         )
97 
98     # exclude direct messages not intended for the user
99     if "direct" in privacy_levels:
100         try:
101             queryset = queryset.exclude(
102                 ~Q(Q(user=viewer) | Q(mention_users=viewer)), privacy="direct"
103             )
104         except FieldError:
105             queryset = queryset.exclude(~Q(user=viewer), privacy="direct")
106 
107     return queryset
108 
109 
110 def handle_remote_webfinger(query):
111     """ webfingerin' other servers """
112     user = None
113 
114     # usernames could be @user@domain or user@domain
115     if not query:
116         return None
117 
118     if query[0] == "@":
119         query = query[1:]
120 
121     try:
122         domain = query.split("@")[1]
123     except IndexError:
124         return None
125 
126     try:
127         user = models.User.objects.get(username=query)
128     except models.User.DoesNotExist:
129         url = "https://%s/.well-known/webfinger?resource=acct:%s" % (domain, query)
130         try:
131             data = get_data(url)
132         except (ConnectorException, HTTPError):
133             return None
134 
135         for link in data.get("links"):
136             if link.get("rel") == "self":
137                 try:
138                     user = activitypub.resolve_remote_id(
139                         link["href"], model=models.User
140                     )
141                 except KeyError:
142                     return None
143     return user
144 
145 
146 def get_edition(book_id):
147     """ look up a book in the db and return an edition """
148     book = models.Book.objects.select_subclasses().get(id=book_id)
149     if isinstance(book, models.Work):
150         book = book.get_default_edition()
151     return book
152 
153 
154 def handle_reading_status(user, shelf, book, privacy):
155     """ post about a user reading a book """
156     # tell the world about this cool thing that happened
157     try:
158         message = {
159             "to-read": "wants to read",
160             "reading": "started reading",
161             "read": "finished reading",
162         }[shelf.identifier]
163     except KeyError:
164         # it's a non-standard shelf, don't worry about it
165         return
166 
167     status = create_generated_note(user, message, mention_books=[book], privacy=privacy)
168     status.save()
169 
170 
171 def is_blocked(viewer, user):
172     """ is this viewer blocked by the user? """
173     if viewer.is_authenticated and viewer in user.blocks.all():
174         return True
175     return False
176 
177 
178 def get_discover_books():
179     """ list of books for the discover page """
180     return list(
181         set(
182             models.Edition.objects.filter(
183                 review__published_date__isnull=False,
184                 review__deleted=False,
185                 review__user__local=True,
186                 review__privacy__in=["public", "unlisted"],
187             )
188             .exclude(cover__exact="")
189             .annotate(Max("review__published_date"))
190             .order_by("-review__published_date__max")[:6]
191         )
192     )
193 
194 
195 def get_suggested_users(user, *args, **kwargs):
196     """ Users, annotated with things they have in common """
197     return (
198         models.User.objects.filter(discoverable=True, is_active=True, *args, **kwargs)
199         .exclude(Q(id__in=user.blocks.all()) | Q(blocks=user))
200         .annotate(
201             mutuals=Count(
202                 "following",
203                 filter=Q(
204                     ~Q(id=user.id),
205                     ~Q(id__in=user.following.all()),
206                     following__in=user.following.all(),
207                 ),
208             ),
209             shared_books=Count(
210                 "shelfbook",
211                 filter=Q(
212                     ~Q(id=user.id),
213                     shelfbook__book__parent_work__in=[
214                         s.book.parent_work for s in user.shelfbook_set.all()
215                     ],
216                 ),
217             ),
218         )
219     )
220
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/bookwyrm/views/helpers.py b/bookwyrm/views/helpers.py
--- a/bookwyrm/views/helpers.py
+++ b/bookwyrm/views/helpers.py
@@ -205,6 +205,7 @@
                     ~Q(id__in=user.following.all()),
                     following__in=user.following.all(),
                 ),
+                distinct=True,
             ),
             shared_books=Count(
                 "shelfbook",
@@ -214,6 +215,7 @@
                         s.book.parent_work for s in user.shelfbook_set.all()
                     ],
                 ),
+                distinct=True,
             ),
         )
     )

{"golden_diff": "diff --git a/bookwyrm/views/helpers.py b/bookwyrm/views/helpers.py\n--- a/bookwyrm/views/helpers.py\n+++ b/bookwyrm/views/helpers.py\n@@ -205,6 +205,7 @@\n                     ~Q(id__in=user.following.all()),\n                     following__in=user.following.all(),\n                 ),\n+                distinct=True,\n             ),\n             shared_books=Count(\n                 \"shelfbook\",\n@@ -214,6 +215,7 @@\n                         s.book.parent_work for s in user.shelfbook_set.all()\n                     ],\n                 ),\n+                distinct=True,\n             ),\n         )\n     )\n", "issue": "Number of followers of suggested users is wrong\n**Describe the bug**\r\nRecommendations for new users to follow in my feed appear with a number of followers we have in common, but that number looks off. The user recommendation I saw said they had 306 followers I follow, but neither of us has that many followers.\r\n\r\n**To Reproduce**\r\nSteps to reproduce the behavior:\r\n1. Go to your home feed after logging in\r\n3. Scroll down until you see a recommendation for a user to follow\r\n4. See the weird follower count\r\n\r\n**Expected behavior**\r\nThe number of mutual followers should be accurate \r\n\r\n**Screenshots**\r\nIf applicable, add screenshots to help explain your problem.\r\n\r\nScreenshot\r\n![409385BB-8652-4B7C-9137-5B6CDB7F0866](https://user-images.githubusercontent.com/1128631/112738864-2ca94580-8f3d-11eb-92af-a86dc7148986.jpeg)\r\n\r\n**Smartphone (please complete the following information):**\r\n    - Device: iPhone 11\r\n    - OS: \r\n    - Browser safari\r\n    - Version\r\n\r\n**Additional context**\r\n\r\n\n", "before_files": [{"content": "\"\"\" helper functions used in various views \"\"\"\nimport re\nfrom requests import HTTPError\nfrom django.core.exceptions import FieldError\nfrom django.db.models import Count, Max, Q\n\nfrom bookwyrm import activitypub, models\nfrom bookwyrm.connectors import ConnectorException, get_data\nfrom bookwyrm.status import create_generated_note\nfrom bookwyrm.utils import regex\n\n\ndef get_user_from_username(viewer, username):\n    \"\"\" helper function to resolve a localname or a username to a user \"\"\"\n    # raises DoesNotExist if user is now found\n    try:\n        return models.User.viewer_aware_objects(viewer).get(localname=username)\n    except models.User.DoesNotExist:\n        return models.User.viewer_aware_objects(viewer).get(username=username)\n\n\ndef is_api_request(request):\n    \"\"\" check whether a request is asking for html or data \"\"\"\n    return \"json\" in request.headers.get(\"Accept\") or request.path[-5:] == \".json\"\n\n\ndef is_bookwyrm_request(request):\n    \"\"\" check if the request is coming from another bookwyrm instance \"\"\"\n    user_agent = request.headers.get(\"User-Agent\")\n    if user_agent is None or re.search(regex.bookwyrm_user_agent, user_agent) is None:\n        return False\n    return True\n\n\ndef object_visible_to_user(viewer, obj):\n    \"\"\" is a user authorized to view an object? \"\"\"\n    if not obj:\n        return False\n\n    # viewer can't see it if the object's owner blocked them\n    if viewer in obj.user.blocks.all():\n        return False\n\n    # you can see your own posts and any public or unlisted posts\n    if viewer == obj.user or obj.privacy in [\"public\", \"unlisted\"]:\n        return True\n\n    # you can see the followers only posts of people you follow\n    if obj.privacy == \"followers\" and obj.user.followers.filter(id=viewer.id).first():\n        return True\n\n    # you can see dms you are tagged in\n    if isinstance(obj, models.Status):\n        if obj.privacy == \"direct\" and obj.mention_users.filter(id=viewer.id).first():\n            return True\n    return False\n\n\ndef privacy_filter(viewer, queryset, privacy_levels=None, following_only=False):\n    \"\"\" filter objects that have \"user\" and \"privacy\" fields \"\"\"\n    privacy_levels = privacy_levels or [\"public\", \"unlisted\", \"followers\", \"direct\"]\n    # if there'd a deleted field, exclude deleted items\n    try:\n        queryset = queryset.filter(deleted=False)\n    except FieldError:\n        pass\n\n    # exclude blocks from both directions\n    if not viewer.is_anonymous:\n        blocked = models.User.objects.filter(id__in=viewer.blocks.all()).all()\n        queryset = queryset.exclude(Q(user__in=blocked) | Q(user__blocks=viewer))\n\n    # you can't see followers only or direct messages if you're not logged in\n    if viewer.is_anonymous:\n        privacy_levels = [p for p in privacy_levels if not p in [\"followers\", \"direct\"]]\n\n    # filter to only privided privacy levels\n    queryset = queryset.filter(privacy__in=privacy_levels)\n\n    # only include statuses the user follows\n    if following_only:\n        queryset = queryset.exclude(\n            ~Q(  # remove everythign except\n                Q(user__in=viewer.following.all())\n                | Q(user=viewer)  # user following\n                | Q(mention_users=viewer)  # is self  # mentions user\n            ),\n        )\n    # exclude followers-only statuses the user doesn't follow\n    elif \"followers\" in privacy_levels:\n        queryset = queryset.exclude(\n            ~Q(  # user isn't following and it isn't their own status\n                Q(user__in=viewer.following.all()) | Q(user=viewer)\n            ),\n            privacy=\"followers\",  # and the status is followers only\n        )\n\n    # exclude direct messages not intended for the user\n    if \"direct\" in privacy_levels:\n        try:\n            queryset = queryset.exclude(\n                ~Q(Q(user=viewer) | Q(mention_users=viewer)), privacy=\"direct\"\n            )\n        except FieldError:\n            queryset = queryset.exclude(~Q(user=viewer), privacy=\"direct\")\n\n    return queryset\n\n\ndef handle_remote_webfinger(query):\n    \"\"\" webfingerin' other servers \"\"\"\n    user = None\n\n    # usernames could be @user@domain or user@domain\n    if not query:\n        return None\n\n    if query[0] == \"@\":\n        query = query[1:]\n\n    try:\n        domain = query.split(\"@\")[1]\n    except IndexError:\n        return None\n\n    try:\n        user = models.User.objects.get(username=query)\n    except models.User.DoesNotExist:\n        url = \"https://%s/.well-known/webfinger?resource=acct:%s\" % (domain, query)\n        try:\n            data = get_data(url)\n        except (ConnectorException, HTTPError):\n            return None\n\n        for link in data.get(\"links\"):\n            if link.get(\"rel\") == \"self\":\n                try:\n                    user = activitypub.resolve_remote_id(\n                        link[\"href\"], model=models.User\n                    )\n                except KeyError:\n                    return None\n    return user\n\n\ndef get_edition(book_id):\n    \"\"\" look up a book in the db and return an edition \"\"\"\n    book = models.Book.objects.select_subclasses().get(id=book_id)\n    if isinstance(book, models.Work):\n        book = book.get_default_edition()\n    return book\n\n\ndef handle_reading_status(user, shelf, book, privacy):\n    \"\"\" post about a user reading a book \"\"\"\n    # tell the world about this cool thing that happened\n    try:\n        message = {\n            \"to-read\": \"wants to read\",\n            \"reading\": \"started reading\",\n            \"read\": \"finished reading\",\n        }[shelf.identifier]\n    except KeyError:\n        # it's a non-standard shelf, don't worry about it\n        return\n\n    status = create_generated_note(user, message, mention_books=[book], privacy=privacy)\n    status.save()\n\n\ndef is_blocked(viewer, user):\n    \"\"\" is this viewer blocked by the user? \"\"\"\n    if viewer.is_authenticated and viewer in user.blocks.all():\n        return True\n    return False\n\n\ndef get_discover_books():\n    \"\"\" list of books for the discover page \"\"\"\n    return list(\n        set(\n            models.Edition.objects.filter(\n                review__published_date__isnull=False,\n                review__deleted=False,\n                review__user__local=True,\n                review__privacy__in=[\"public\", \"unlisted\"],\n            )\n            .exclude(cover__exact=\"\")\n            .annotate(Max(\"review__published_date\"))\n            .order_by(\"-review__published_date__max\")[:6]\n        )\n    )\n\n\ndef get_suggested_users(user, *args, **kwargs):\n    \"\"\" Users, annotated with things they have in common \"\"\"\n    return (\n        models.User.objects.filter(discoverable=True, is_active=True, *args, **kwargs)\n        .exclude(Q(id__in=user.blocks.all()) | Q(blocks=user))\n        .annotate(\n            mutuals=Count(\n                \"following\",\n                filter=Q(\n                    ~Q(id=user.id),\n                    ~Q(id__in=user.following.all()),\n                    following__in=user.following.all(),\n                ),\n            ),\n            shared_books=Count(\n                \"shelfbook\",\n                filter=Q(\n                    ~Q(id=user.id),\n                    shelfbook__book__parent_work__in=[\n                        s.book.parent_work for s in user.shelfbook_set.all()\n                    ],\n                ),\n            ),\n        )\n    )\n", "path": "bookwyrm/views/helpers.py"}], "after_files": [{"content": "\"\"\" helper functions used in various views \"\"\"\nimport re\nfrom requests import HTTPError\nfrom django.core.exceptions import FieldError\nfrom django.db.models import Count, Max, Q\n\nfrom bookwyrm import activitypub, models\nfrom bookwyrm.connectors import ConnectorException, get_data\nfrom bookwyrm.status import create_generated_note\nfrom bookwyrm.utils import regex\n\n\ndef get_user_from_username(viewer, username):\n    \"\"\" helper function to resolve a localname or a username to a user \"\"\"\n    # raises DoesNotExist if user is now found\n    try:\n        return models.User.viewer_aware_objects(viewer).get(localname=username)\n    except models.User.DoesNotExist:\n        return models.User.viewer_aware_objects(viewer).get(username=username)\n\n\ndef is_api_request(request):\n    \"\"\" check whether a request is asking for html or data \"\"\"\n    return \"json\" in request.headers.get(\"Accept\") or request.path[-5:] == \".json\"\n\n\ndef is_bookwyrm_request(request):\n    \"\"\" check if the request is coming from another bookwyrm instance \"\"\"\n    user_agent = request.headers.get(\"User-Agent\")\n    if user_agent is None or re.search(regex.bookwyrm_user_agent, user_agent) is None:\n        return False\n    return True\n\n\ndef object_visible_to_user(viewer, obj):\n    \"\"\" is a user authorized to view an object? \"\"\"\n    if not obj:\n        return False\n\n    # viewer can't see it if the object's owner blocked them\n    if viewer in obj.user.blocks.all():\n        return False\n\n    # you can see your own posts and any public or unlisted posts\n    if viewer == obj.user or obj.privacy in [\"public\", \"unlisted\"]:\n        return True\n\n    # you can see the followers only posts of people you follow\n    if obj.privacy == \"followers\" and obj.user.followers.filter(id=viewer.id).first():\n        return True\n\n    # you can see dms you are tagged in\n    if isinstance(obj, models.Status):\n        if obj.privacy == \"direct\" and obj.mention_users.filter(id=viewer.id).first():\n            return True\n    return False\n\n\ndef privacy_filter(viewer, queryset, privacy_levels=None, following_only=False):\n    \"\"\" filter objects that have \"user\" and \"privacy\" fields \"\"\"\n    privacy_levels = privacy_levels or [\"public\", \"unlisted\", \"followers\", \"direct\"]\n    # if there'd a deleted field, exclude deleted items\n    try:\n        queryset = queryset.filter(deleted=False)\n    except FieldError:\n        pass\n\n    # exclude blocks from both directions\n    if not viewer.is_anonymous:\n        blocked = models.User.objects.filter(id__in=viewer.blocks.all()).all()\n        queryset = queryset.exclude(Q(user__in=blocked) | Q(user__blocks=viewer))\n\n    # you can't see followers only or direct messages if you're not logged in\n    if viewer.is_anonymous:\n        privacy_levels = [p for p in privacy_levels if not p in [\"followers\", \"direct\"]]\n\n    # filter to only privided privacy levels\n    queryset = queryset.filter(privacy__in=privacy_levels)\n\n    # only include statuses the user follows\n    if following_only:\n        queryset = queryset.exclude(\n            ~Q(  # remove everythign except\n                Q(user__in=viewer.following.all())\n                | Q(user=viewer)  # user following\n                | Q(mention_users=viewer)  # is self  # mentions user\n            ),\n        )\n    # exclude followers-only statuses the user doesn't follow\n    elif \"followers\" in privacy_levels:\n        queryset = queryset.exclude(\n            ~Q(  # user isn't following and it isn't their own status\n                Q(user__in=viewer.following.all()) | Q(user=viewer)\n            ),\n            privacy=\"followers\",  # and the status is followers only\n        )\n\n    # exclude direct messages not intended for the user\n    if \"direct\" in privacy_levels:\n        try:\n            queryset = queryset.exclude(\n                ~Q(Q(user=viewer) | Q(mention_users=viewer)), privacy=\"direct\"\n            )\n        except FieldError:\n            queryset = queryset.exclude(~Q(user=viewer), privacy=\"direct\")\n\n    return queryset\n\n\ndef handle_remote_webfinger(query):\n    \"\"\" webfingerin' other servers \"\"\"\n    user = None\n\n    # usernames could be @user@domain or user@domain\n    if not query:\n        return None\n\n    if query[0] == \"@\":\n        query = query[1:]\n\n    try:\n        domain = query.split(\"@\")[1]\n    except IndexError:\n        return None\n\n    try:\n        user = models.User.objects.get(username=query)\n    except models.User.DoesNotExist:\n        url = \"https://%s/.well-known/webfinger?resource=acct:%s\" % (domain, query)\n        try:\n            data = get_data(url)\n        except (ConnectorException, HTTPError):\n            return None\n\n        for link in data.get(\"links\"):\n            if link.get(\"rel\") == \"self\":\n                try:\n                    user = activitypub.resolve_remote_id(\n                        link[\"href\"], model=models.User\n                    )\n                except KeyError:\n                    return None\n    return user\n\n\ndef get_edition(book_id):\n    \"\"\" look up a book in the db and return an edition \"\"\"\n    book = models.Book.objects.select_subclasses().get(id=book_id)\n    if isinstance(book, models.Work):\n        book = book.get_default_edition()\n    return book\n\n\ndef handle_reading_status(user, shelf, book, privacy):\n    \"\"\" post about a user reading a book \"\"\"\n    # tell the world about this cool thing that happened\n    try:\n        message = {\n            \"to-read\": \"wants to read\",\n            \"reading\": \"started reading\",\n            \"read\": \"finished reading\",\n        }[shelf.identifier]\n    except KeyError:\n        # it's a non-standard shelf, don't worry about it\n        return\n\n    status = create_generated_note(user, message, mention_books=[book], privacy=privacy)\n    status.save()\n\n\ndef is_blocked(viewer, user):\n    \"\"\" is this viewer blocked by the user? \"\"\"\n    if viewer.is_authenticated and viewer in user.blocks.all():\n        return True\n    return False\n\n\ndef get_discover_books():\n    \"\"\" list of books for the discover page \"\"\"\n    return list(\n        set(\n            models.Edition.objects.filter(\n                review__published_date__isnull=False,\n                review__deleted=False,\n                review__user__local=True,\n                review__privacy__in=[\"public\", \"unlisted\"],\n            )\n            .exclude(cover__exact=\"\")\n            .annotate(Max(\"review__published_date\"))\n            .order_by(\"-review__published_date__max\")[:6]\n        )\n    )\n\n\ndef get_suggested_users(user, *args, **kwargs):\n    \"\"\" Users, annotated with things they have in common \"\"\"\n    return (\n        models.User.objects.filter(discoverable=True, is_active=True, *args, **kwargs)\n        .exclude(Q(id__in=user.blocks.all()) | Q(blocks=user))\n        .annotate(\n            mutuals=Count(\n                \"following\",\n                filter=Q(\n                    ~Q(id=user.id),\n                    ~Q(id__in=user.following.all()),\n                    following__in=user.following.all(),\n                ),\n                distinct=True,\n            ),\n            shared_books=Count(\n                \"shelfbook\",\n                filter=Q(\n                    ~Q(id=user.id),\n                    shelfbook__book__parent_work__in=[\n                        s.book.parent_work for s in user.shelfbook_set.all()\n                    ],\n                ),\n                distinct=True,\n            ),\n        )\n    )\n", "path": "bookwyrm/views/helpers.py"}]}