delete_users --real-phones: every phone user except the demo logins

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 02:41:16 +03:30
parent 39247f6d53
commit e9d676ce68
2 changed files with 21 additions and 1 deletions

View File

@@ -15,6 +15,11 @@
python manage.py delete_users --phones 09121234567 09351234567 python manage.py delete_users --phones 09121234567 09351234567
python manage.py delete_users --ids 17 22 --yes python manage.py delete_users --ids 17 22 --yes
python manage.py delete_users --real-phones # هر کاربرِ شماره‌دار جز شماره‌های دمو
`--real-phones` یعنی هر کاربری که شماره دارد و شماره‌اش در TEST_LOGIN_PHONES (حساب‌های دمو با کدِ
ثابت) نیست. شماره‌ها از سرور بیرون نمی‌آیند؛ گزارش فقط چهار رقمِ اول و سه رقمِ آخر را نشان می‌دهد.
مهمان‌ها (بی‌شماره) با این گزینه انتخاب نمی‌شوند.
سفارشِ پرداخت‌شده سندِ مالی است؛ کاربری که سفارشِ «paid» دارد بدونِ --include-paid پاک نمی‌شود. سفارشِ پرداخت‌شده سندِ مالی است؛ کاربری که سفارشِ «paid» دارد بدونِ --include-paid پاک نمی‌شود.
""" """
@@ -64,6 +69,8 @@ class Command(BaseCommand):
def add_arguments(self, parser): def add_arguments(self, parser):
parser.add_argument('--phones', nargs='*', default=[]) parser.add_argument('--phones', nargs='*', default=[])
parser.add_argument('--ids', nargs='*', type=int, default=[]) parser.add_argument('--ids', nargs='*', type=int, default=[])
parser.add_argument('--real-phones', action='store_true',
help='همه‌ی کاربرهای شماره‌دار جز شماره‌های TEST_LOGIN_PHONES.')
parser.add_argument('--yes', action='store_true', help='واقعاً پاک کن.') parser.add_argument('--yes', action='store_true', help='واقعاً پاک کن.')
parser.add_argument('--include-paid', action='store_true', parser.add_argument('--include-paid', action='store_true',
help='کاربرِ دارای سفارشِ پرداخت‌شده را هم پاک کن.') help='کاربرِ دارای سفارشِ پرداخت‌شده را هم پاک کن.')
@@ -71,6 +78,11 @@ class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
phones = [normalize_phone(p) or p for p in options['phones']] phones = [normalize_phone(p) or p for p in options['phones']]
users = list(User.objects.filter(phone__in=phones)) + list(User.objects.filter(pk__in=options['ids'])) users = list(User.objects.filter(phone__in=phones)) + list(User.objects.filter(pk__in=options['ids']))
if options['real_phones']:
from django.conf import settings
users += list(User.objects.exclude(phone=None).exclude(phone='')
.exclude(phone__in=list(settings.TEST_LOGIN_PHONES)))
users = list({u.pk: u for u in users}.values()) users = list({u.pk: u for u in users}.values())
missing = set(phones) - {u.phone for u in users} missing = set(phones) - {u.phone for u in users}
if missing: if missing:

View File

@@ -2,7 +2,7 @@
from io import StringIO from io import StringIO
from django.core.management import CommandError, call_command from django.core.management import CommandError, call_command
from django.test import TestCase from django.test import TestCase, override_settings
from accounts.models import OTPCode, Profile, User from accounts.models import OTPCode, Profile, User
from ai_tutor.models import Conversation, Message from ai_tutor.models import Conversation, Message
@@ -49,3 +49,11 @@ class DeleteUsersTests(TestCase):
self.assertTrue(User.objects.filter(pk=self.doomed.pk).exists()) self.assertTrue(User.objects.filter(pk=self.doomed.pk).exists())
self.run_command('--ids', str(self.doomed.pk), '--yes', '--include-paid') self.run_command('--ids', str(self.doomed.pk), '--yes', '--include-paid')
self.assertFalse(Order.objects.filter(user_id=self.doomed.pk).exists()) self.assertFalse(Order.objects.filter(user_id=self.doomed.pk).exists())
@override_settings(TEST_LOGIN_PHONES={'09121110002': '1234'})
def test_real_phones_keeps_demo_numbers_and_guests(self):
guest = User.objects.create(device_id='guest-x', is_guest=True)
self.run_command('--real-phones', '--yes')
self.assertFalse(User.objects.filter(pk=self.doomed.pk).exists())
self.assertTrue(User.objects.filter(pk=self.kept.pk).exists())
self.assertTrue(User.objects.filter(pk=guest.pk).exists())