Как извлекать случайные записи из 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)