Home > Software design >  Queryset random order specific to each user with pagination in Django
Queryset random order specific to each user with pagination in Django

Time:07-09

I want to order queryset randomly which is fixed for each user. When I use order_by("?") order change each time but I want different order for each user than don't change next time. For example for user one order is <QuerySet [obj1, obj5, obj3, obj4, obj2]> and for user two is <QuerySet [obj5, obj2, obj1, obj3, obj4]> and order for user one don't change but is different from other users. How can I do this?

CodePudding user response:

Django don't have any inbuilt feature to do that kind of shuff. But you can implement that by your own.

To implement that, you need to save a random seed value corresponding to a user. I believe you have a user id associated with a user, you can use that as a seed value.

Now you have to use that seed value in Python's built-in random to generate a random shuffle.

Example:

import random

numbers = [10, 20, 30, 40, 50, 60]
print("Original list: ", numbers)
random.seed(4)
random.shuffle(numbers)
print("Shuffled list ", numbers)
# Output [40, 60, 50, 10, 30, 20]

random.seed(4)
random.shuffle(numbers)
print("Reshuffled list ", numbers)
# Output [40, 60, 50, 10, 30, 20]

random.seed(5)
random.shuffle(numbers)
print("Reshuffled list ", numbers)
# Output [60, 40, 10, 20, 30, 50]

Convert the same QuerySet into a list and pass it to random.shuffle(qs_list) and get the user id and pass it to random.seed(user_id).

Example:

import random
random.seed(user_id)
random.shuffle(qs_list)
# qs_list is shuffled according to user's id

CodePudding user response:

You can do it in multiple ways and it depends on if the main queryset will be changing (adding/removing instances). The easiest way is to store the randomized queryset as variable in User model. It can be i.e. CharField that is going to store id's divided by commas.

models.py

User(...):
    ...
    my_queryset = models.CharField("My QuerySet", max_lenght=512, default="")

    def set_queryset(self, queryset):
        self.my_queryset = ",".join([x.id for x in queryset])
        self.save()

    def get_queryset(self):
        list_of_ids = [int(x) for x in self.my_queryset.split(",")]
        queryset = [queryset.append(MyModel.objects.get(id=i)) for i in list_of_ids]
        return queryset
    

usage:

user = User.objects.get(id=1)
randomized_qs = [obj1, obj5, obj3, obj4, obj2]

user.get_queryset()   # gives []
if not user.my_queryset:
    user.set_queryset(randomized_qs)
user.get_queryset()   # gives [obj1, obj5, obj3, obj4, obj2]
  • Related