From e9d676ce689cb49ec2dccbe061399454de0b656b Mon Sep 17 00:00:00 2001 From: Zareian Date: Fri, 2 Oct 2026 02:41:16 +0330 Subject: [PATCH] delete_users --real-phones: every phone user except the demo logins Co-Authored-By: Claude Opus 5.5 --- accounts/management/commands/delete_users.py | 12 ++++++++++++ accounts/tests_delete_users.py | 10 +++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/accounts/management/commands/delete_users.py b/accounts/management/commands/delete_users.py index 314e663..38799cb 100644 --- a/accounts/management/commands/delete_users.py +++ b/accounts/management/commands/delete_users.py @@ -15,6 +15,11 @@ python manage.py delete_users --phones 09121234567 09351234567 python manage.py delete_users --ids 17 22 --yes + python manage.py delete_users --real-phones # هر کاربرِ شماره‌دار جز شماره‌های دمو + +`--real-phones` یعنی هر کاربری که شماره دارد و شماره‌اش در TEST_LOGIN_PHONES (حساب‌های دمو با کدِ +ثابت) نیست. شماره‌ها از سرور بیرون نمی‌آیند؛ گزارش فقط چهار رقمِ اول و سه رقمِ آخر را نشان می‌دهد. +مهمان‌ها (بی‌شماره) با این گزینه انتخاب نمی‌شوند. سفارشِ پرداخت‌شده سندِ مالی است؛ کاربری که سفارشِ «paid» دارد بدونِ --include-paid پاک نمی‌شود. """ @@ -64,6 +69,8 @@ class Command(BaseCommand): def add_arguments(self, parser): parser.add_argument('--phones', nargs='*', 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('--include-paid', action='store_true', help='کاربرِ دارای سفارشِ پرداخت‌شده را هم پاک کن.') @@ -71,6 +78,11 @@ class Command(BaseCommand): def handle(self, *args, **options): 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'])) + 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()) missing = set(phones) - {u.phone for u in users} if missing: diff --git a/accounts/tests_delete_users.py b/accounts/tests_delete_users.py index 4072e27..1aa1a78 100644 --- a/accounts/tests_delete_users.py +++ b/accounts/tests_delete_users.py @@ -2,7 +2,7 @@ from io import StringIO 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 ai_tutor.models import Conversation, Message @@ -49,3 +49,11 @@ class DeleteUsersTests(TestCase): self.assertTrue(User.objects.filter(pk=self.doomed.pk).exists()) self.run_command('--ids', str(self.doomed.pk), '--yes', '--include-paid') 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())