1

I want to have items with random annotations.

I tried this:

items = Item.objects.all().annotate(random_value=Value(randint(1,6)),output_field=PositiveIntegerField()))

And it is random, but THE SAME for EVERY Item in QuerySet.

But I want to have DIFFERENT value for EACH Item...

Any ideas?

Tomasz Brzezina
  • 1,452
  • 5
  • 21
  • 44

1 Answers1

1

According @Willem Van Onsem suggestion it is possible in Django<3.2:

def my_view(request):
    from django.db.models.expressions import Func
    from django.db.models.functions.mixins import (
        FixDecimalInputMixin, NumericOutputFieldMixin,
    )
    class Random(NumericOutputFieldMixin, Func):
       function = 'RANDOM'
       arity = 0

       def as_mysql(self, compiler, connection, **extra_context):
           return super().as_sql(compiler, connection, function='RAND', **extra_context)

       def as_oracle(self, compiler, connection, **extra_context):
           return super().as_sql(compiler, connection, function='DBMS_RANDOM.VALUE', **extra_context)

       def as_sqlite(self, compiler, connection, **extra_context):
           return super().as_sql(compiler, connection, function='RAND', **extra_context)

       def get_group_by_cols(self, alias=None):
           return []


    items = Item.objects.all().annotate(random_value=Round(Random()*5+1))

I did it inside def my_view, because if 3.2 becomes stable I remove this and add global from django.models.db import Round

Tomasz Brzezina
  • 1,452
  • 5
  • 21
  • 44