1
1
# Generated by Django 4.2.21 on 2025-07-10 17:28
2
2
3
+ from django .conf import settings
3
4
from django .db import migrations
4
- from django .db .models import Count
5
+ from django .db .models import Exists , F , OuterRef
5
6
6
7
7
8
def delete_email_addresses_for_dummy_users (apps , schema_editor ):
8
9
EmailAddress = apps .get_model ("account" , "EmailAddress" )
10
+ SocialAccount = apps .get_model ("socialaccount" , "SocialAccount" )
9
11
12
+ social_accounts = SocialAccount .objects .filter (user = OuterRef ("user" ))
10
13
# delete EmailAddress records for dummy users that were created by invitations
11
- EmailAddress .objects .filter (verified = False ).annotate (
12
- social_accounts_count = Count ("user__socialaccount" )
13
- ).filter (
14
- social_accounts_count = 0 , user__password__startswith = "!" # nosec
14
+ EmailAddress .objects .filter (
15
+ ~ Exists (social_accounts ), verified = False , user__password__startswith = "!" # nosec
15
16
).delete ()
16
17
17
18
18
- def normalize_email_case_mismatches (apps , schema_editor ):
19
+ def restore_email_addresses_for_dummy_users (apps , schema_editor ):
20
+ User = apps .get_model (settings .AUTH_USER_MODEL )
19
21
EmailAddress = apps .get_model ("account" , "EmailAddress" )
22
+ SocialAccount = apps .get_model ("socialaccount" , "SocialAccount" )
20
23
21
- # fix case-related mismatches between User.email and EmailAddress.email
22
- email_addresses = (
23
- EmailAddress .objects .filter (verified = True )
24
- .annotate (social_accounts_count = Count ("user__socialaccount" ))
25
- .filter (social_accounts_count = 0 )
26
- .select_related ("user" )
24
+ social_accounts = SocialAccount .objects .filter (user = OuterRef ("user" ))
25
+ email_addresses = EmailAddress .objects .filter (user = OuterRef ("user" ))
26
+ dummy_users = (
27
+ User .objects .filter (password__startswith = "!" )
28
+ .annotate (
29
+ has_social_account = Exists (social_accounts ), has_email_address = Exists (email_addresses )
30
+ )
31
+ .filter (has_social_account = False , has_email_address = False )
27
32
)
28
- email_addresses_to_update = []
29
33
30
- for email_address in email_addresses :
31
- user_email = email_address .user .email
32
- if email_address .email .lower () == user_email .lower () and email_address .email != user_email :
33
- email_address .email = user_email
34
- email_addresses_to_update .append (email_address )
35
- EmailAddress .objects .bulk_update (email_addresses_to_update , ["email" ])
34
+ email_addresses_to_create = [
35
+ EmailAddress (email = user .email , user = user , primary = True , verified = False )
36
+ for user in dummy_users
37
+ ]
38
+ EmailAddress .objects .bulk_create (email_addresses_to_create )
39
+
40
+
41
+ def normalize_email_case_mismatches (apps , schema_editor ):
42
+ EmailAddress = apps .get_model ("account" , "EmailAddress" )
43
+ SocialAccount = apps .get_model ("socialaccount" , "SocialAccount" )
44
+
45
+ social_accounts = SocialAccount .objects .filter (user = OuterRef ("user" ))
46
+ # fix case-related mismatches between User.email and EmailAddress.email
47
+ EmailAddress .objects .filter (
48
+ ~ Exists (social_accounts ), verified = True , email__iexact = F ("user__email" )
49
+ ).exclude (email = F ("user__email" )).update (email = F ("user__email" ))
36
50
37
51
38
52
class Migration (migrations .Migration ):
@@ -44,7 +58,7 @@ class Migration(migrations.Migration):
44
58
operations = [
45
59
migrations .RunPython (
46
60
delete_email_addresses_for_dummy_users ,
47
- reverse_code = migrations . RunPython . noop ,
61
+ reverse_code = restore_email_addresses_for_dummy_users ,
48
62
),
49
63
migrations .RunPython (
50
64
normalize_email_case_mismatches ,
0 commit comments