I am new to Django and I'd need some help for a project I have.
I am currently building the API using Django-Rest-Framework and I would like to have a view which returns a weekly list of exercises. I am not sure how i could make it so the queried objects change weekly...
atm I've created a custom Manager which retrieves a random amount of exercises from the exercise db
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)
CodePudding user response:
I would add a created field to Exercise created = models.DateTimeField(auto_now_add=True)
and then change Exercise.objects.all()
to Exercise.objects.filter(created__gte=datetime.date.today - datetime.timedelta(days=7)
This way you are only querying Exercise objects created in the last 7 days.
CodePudding user response:
As i understand it, you want the list of exercise to be random, but stay the same for the entire week.
To me, the best way would be to create a WeeklyExercise model with a M2M on Exercise and a created_at = models.DateTimeField(auto_now_add=True)
field.
With a periodic script (probably using Celery) you would create a new entry in WeeklyExercise each week.
To populate this row you can do
weekly_exercise = WeeklyExercise.objects.create()
weekly_exercise.exercises.set(*list(Exercise.objects.order_by("?")[:EXERCISE_PER_WEEK]))
To retrieve the exercises for the week you can do WeeklyExercise.objects.order_by("-created_at").first().exercises.all()
If you do not need an history of previous exercices being the weekly exercises, you could just add a is_weekly_exercise = models.BooleanField(default=False)
to your Exercise model.
Your Celery script would only be
Exercise.objects.filter(is_weekly_exercise=True).update(is_weekly_exercise=False)
Exercise.objects.order_by("?")[:EXERCISE_PER_WEEK].update(is_weekly_exercise=True)