diff --git a/dandiapi/api/views/dandiset.py b/dandiapi/api/views/dandiset.py index 706293781..e82ab644f 100644 --- a/dandiapi/api/views/dandiset.py +++ b/dandiapi/api/views/dandiset.py @@ -362,7 +362,7 @@ def unembargo(self, request, dandiset__pk): # TODO: move these into a viewset @action(methods=['GET', 'PUT'], detail=True) def users(self, request, dandiset__pk): - dandiset = self.get_object() + dandiset: Dandiset = self.get_object() if request.method == 'PUT': # Verify that the user is currently an owner response = get_40x_or_None(request, ['owner'], dandiset, return_403=True) @@ -373,14 +373,15 @@ def users(self, request, dandiset__pk): serializer.is_valid(raise_exception=True) def get_user_or_400(username): - # SocialAccount uses the generic JSONField instead of the PostGres JSONFIELD, - # so it is not empowered to do a more powerful query like: - # SocialAccount.objects.get(extra_data__login=username) - # We resort to doing this awkward search instead. - for social_account in SocialAccount.objects.filter(extra_data__icontains=username): - if social_account.extra_data['login'] == username: - return social_account.user - else: + try: + return User.objects.alias( + social_account_username=Subquery( + SocialAccount.objects.filter(user_id=OuterRef('id')).values( + 'extra_data__login' + )[:1] + ) + ).get(social_account_username=username) + except ObjectDoesNotExist: try: return User.objects.get(username=username) except ObjectDoesNotExist: diff --git a/setup.py b/setup.py index a0f136df0..2f38c5850 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,9 @@ 'dandischema~=0.8.4', 'django~=4.1.0', 'django-admin-display', - 'django-allauth', + # Require 0.58.0 as it is the first version to support postgres' native + # JSONField for SocialAccount.extra_data + 'django-allauth>=0.58.0', 'django-click', 'django-configurations[database,email]', 'django-extensions',