Произвольный порядок запросов для каждого пользователя с пагинацией в Django
Я хочу произвольно упорядочить набор запросов, который фиксирован для каждого пользователя. Когда я использую order_by("?")
, порядок меняется каждый раз, но я хочу, чтобы для каждого пользователя был свой порядок, который не будет меняться в следующий раз. Например, для первого пользователя заказ <QuerySet [obj1, obj5, obj3, obj4, obj2]>
, а для второго <QuerySet [obj5, obj2, obj1, obj3, obj4]>
и заказ для первого пользователя не меняется, но отличается от заказов других пользователей. Как я могу это сделать?
В Django нет встроенной функции для такой перестановки. Но вы можете реализовать это самостоятельно.
Чтобы реализовать это, вам нужно сохранить случайное значение seed
, соответствующее пользователю. Я полагаю, что у вас есть идентификатор пользователя, связанный с пользователем, вы можете использовать его в качестве начального значения.
Теперь вам нужно использовать это начальное значение во встроенной в Python программе random
для генерации случайной перестановки.
Пример:
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]
Преобразуйте тот же QuerySet в список и передайте его в random.shuffle(qs_list)
, получите id пользователя и передайте его в random.seed(user_id)
.
Пример:
import random
random.seed(user_id)
random.shuffle(qs_list)
# qs_list is shuffled according to user's id
Вы можете сделать это несколькими способами, и это зависит от того, будет ли меняться основной набор запросов (добавление/удаление экземпляров). Самый простой способ - хранить рандомизированный кверисет как переменную в модели User
. Это может быть, например, CharField
, которая будет хранить идентификаторы, разделенные запятыми.
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
использование:
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]