Home > Mobile >  How to retrieve random records of Django ORM on a weekly basis
How to retrieve random records of Django ORM on a weekly basis

Time:10-23

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)
  • Related