8

I want to set the "default" value as a randomly generated String for the promotion_code part of my Promotion model, for that the code_generate function is used.

The issue with the code below that it seems like default=code_generate() generates this random string once every server start thus assigning the same value. I can see that by the admin panel, every time I try to generate a new Promotion, it gives me the exact same string.

#generate a string, which is not already existing in the earlier Promotion instances
def code_generate():
    while 1:
        from django.conf import settings
        import random, string
        prom_code = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(6))
        try:
            Promotion.objects.get(promotion_code=prom_code)
        except:
            return prom_code

class Promotion(models.Model):
    purchase = models.ForeignKey('Purchase')
    promotion_code = models.CharField(max_length=20,unique=True,default=code_generate())

How can I make it random ?

Regards

Hellnar
  • 62,315
  • 79
  • 204
  • 279

2 Answers2

24

You need to pass a callable as default, not call the callable:

promotion_code = models.CharField(max_length=20,unique=True,default=code_generate)
rz.
  • 19,861
  • 10
  • 54
  • 47
Hellnar
  • 62,315
  • 79
  • 204
  • 279
  • 9
    Just for anyone who's wondering why this is the case, when you include the `()` on the callable, it's called right then and there when the model is defined. So, the **result of that call** becomes the default - so it'll be the same each time. Without the brackets, the default is the callable itself, and Django knows to call it each time to get the correct (different) value. – Daniel Roseman Feb 13 '10 at 17:15
  • 3
    Interestingly, when South freezes a model, the callable is run and its return value is frozen into the `default=` argument in the ` db.create_table(...` statement in the schema migration. – hobs Jul 31 '13 at 19:24
  • 1
    Same issue as hobs's here. How should I avoid that? – Aleksei Petrenko May 29 '14 at 11:52
-3

As indicated in the other answer, the simplest way to get a random string is as follows:

str(random.random())[2:]

Altho' it is a string of numbers. Fair enough, until you would want to replace it eventually with sha.

Community
  • 1
  • 1
lprsd
  • 84,407
  • 47
  • 135
  • 168