Нужно исправить импорты и валидацию, защитить запуск рассылки и вынести отправку из HTTP-запроса. Текущий код неверно фиксирует общий статус и допускает повторную отправку.
Ревью и отладка Django‑кода
Нужно исправить импорты и валидацию, защитить запуск рассылки и вынести отправку из HTTP-запроса. Текущий код неверно фиксирует общий статус и допускает повторную отправку.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Требуется выполнить проверку качества и корректность работы представленного кода Django‑приложения, а при необходимости исправить найденные ошибки.
# push/models.py
from django.db import models
import enums
class PlannedPush(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
is_promo = models.BooleanField(default=False)
status = models.CharField(max_length=255, choices=enums.PushStatus.choises(), default=enums.PushStatus.CREATED)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Push(models.Model):
planned_push = models.ForeignKey(PlannedPush, on_delete=models.CASCADE)
user = models.ForeignKey('users.User', on_delete=models.CASCADE)
status = models.CharField(
max_length=55,
choices=enums.PushStatus.choises(),
default=enums.PushStatus.CREATED
)
sent_at = models.DateTimeField(null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
# push/views.py
from django.http import JsonResponse
import json
from .models import PlannedPush
from .models import Push
from users.models import User
from .utils.ios_push import send_push_to_ios
def create_push(request):
data = json.loads(request.body)
try:
planned_push = PlannedPush.objects.create(
title=data['title'],
body=data['body'],
is_promo=data['is_promo']
)
except KeyError as e:
print(e)
return JsonResponse({'error': 'missing required field'}, status=status.HTTP_400_BAD_REQUEST)
return JsonResponse({'id': planned_push.id}, status=status.HTTP_201_CREATED)
def send_push(request):
data = json.loads(request.body)
try:
planned_push = PlannedPush.objects.get(id=data['planned_push_id'])
except PlannedPush.DoesNotExist:
return JsonResponse({'error': 'planned push not found'}, status=status.HTTP_404_NOT_FOUND)
users = User.objects.all()
for user in users:
if not user.user_settings_set.first().push_enabled:
continue
push = Push.objects.create(
planned_push=planned_push,
user=user
)
for device in user.devices_set.filter(device_type='ios'):
try:
is_sent = send_push_to_ios(device, push.planned_push.title, push.planned_push.body)
except Exception as e:
print(e)
push.status = enums.PushStatus.ERROR
push.save()
continue
if is_sent:
push.status = enums.PushStatus.SENT
push.sent_at = timezone.now()
push.save()
break
planned_push.status = enums.PushStatus.SENT
return JsonResponse({'status': 'ok'}, status=status.HTTP_200_OK)
Ответ
Нужно исправить импорты и валидацию, защитить запуск рассылки и вынести отправку из HTTP-запроса. Текущий код неверно фиксирует общий статус и допускает повторную отправку.
status, timezone и enums в views не импортированы. choises похоже на опечатку, но нужно проверить реальный enum API. Некорректный JSON и отсутствие planned_push_id не обработаны; настройки пользователя могут отсутствовать. planned_push.status меняется без save и объявляется SENT даже при неудачах.
Нужны авторизация, POST-only/CSRF по выбранному контракту, проверка рекламного согласия для promo и уникальность отправки пользователю/устройству. Заранее определите, отправлять на одно устройство или все: текущий break выбирает первое успешное. Массовую работу перенесите в очередь, добавьте retries с учётом результата, итоговые счётчики и безопасные логи. Связи предзагружайте, чтобы избежать N+1.