Как извлекать случайные записи из Django ORM на еженедельной основе

Я новичок в Django и мне нужна помощь для проекта, который у меня есть.

В настоящее время я создаю API, используя Django-Rest-Framework и Я хотел бы иметь представление, которое возвращает еженедельный список упражнений. Я не уверен, как я могу сделать так, чтобы запрашиваемые объекты менялись еженедельно...

atm Я создал пользовательский менеджер, который извлекает случайное количество упражнений из базы данных упражнений

Models.py

class ExerciseManager(models.Manager):
    def random(self, amount=20):
        random_exercises = []
        exercises = Exercise.objects.all()
        for i in range(amount):
            random_exercises.append(random.choice(exercises))
        return random_exercises


class Exercise(models.Model):
    name = models.CharField(max_length=100, unique=True)
    objects = ExerciseManager()

    def __str__(self):
        return f"{self.name}"

views.py

@api_view(['GET'])
def exercise_list(request):
    exercises = Exercise.objects.random()
    serializer = ExerciseSerializer(exercises, many=True)
    return Response(serializer.data)

Я бы добавил поле created к Exercise created = models.DateTimeField(auto_now_add=True) и затем изменил Exercise.objects.all() на Exercise.objects.filter(created__gte=datetime.date.today - datetime.timedelta(days=7) Таким образом, вы будете запрашивать только объекты Exercise, созданные за последние 7 дней.

Как я понимаю, вы хотите, чтобы список упражнений был случайным, но оставался неизменным в течение всей недели.
На мой взгляд, лучшим способом будет создание модели WeeklyExercise с M2M на Exercise и полем created_at = models.DateTimeField(auto_now_add=True). С помощью периодического скрипта (возможно, с использованием Celery) вы будете создавать новую запись в WeeklyExercise каждую неделю.

Чтобы заполнить этот ряд, вы можете сделать

weekly_exercise = WeeklyExercise.objects.create()
weekly_exercise.exercises.set(*list(Exercise.objects.order_by("?")[:EXERCISE_PER_WEEK]))

Чтобы получить упражнения на неделю, вы можете сделать WeeklyExercise.objects.order_by("-created_at").first().exercises.all()

Если вам не нужна история предыдущих упражнений в качестве еженедельных упражнений, вы можете просто добавить is_weekly_exercise = models.BooleanField(default=False) к вашей модели Exercise.
Ваш сценарий Celery будет только

Exercise.objects.filter(is_weekly_exercise=True).update(is_weekly_exercise=False)
Exercise.objects.order_by("?")[:EXERCISE_PER_WEEK].update(is_weekly_exercise=True)
Вернуться на верх