pythonmysqldjangodjango-modelsrandom

How to generate a random product_id int to MySQL when adding a new product via Django Admin


I'm trying to add a "product_id" alongside new products to a MySQL database for use in an ecommerce website running Django. I then want to use these product_id values to be searchable from within the eCommerce site. For this reason they only need to be 5 characters long.

The product class in models.py looks like this:

from django.utils.crypto import get_random_string

class Product(models.Model):
    title = models.CharField(max_length=255)
    slug = models.SlugField(max_length=255)
    category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
    product_id = models.IntegerField(get_random_string(5, 1234567890))  # Max length 5, numerals only
    description = models.TextField(blank=True, null=True)
    price = models.FloatField()

When trying to migrate the models to the MySQL server I get:

File "C:\Users\user\Desktop\ecommerce\apps\store\models.py", line 18, in <module>
   class Product(models.Model):
 File "C:\Users\user\Desktop\ecommerce\apps\store\models.py", line 22, in Product
   product_id = models.IntegerField(get_random_string(5, 1234567890))  # Create a random numeric id for each product
 File "C:\Users\user\Desktop\ecommerce\venv\lib\site-packages\django\utils\crypto.py", line 74, in get_random_string
   return ''.join(secrets.choice(allowed_chars) for i in range(length))
 File "C:\Users\user\Desktop\ecommerce\venv\lib\site-packages\django\utils\crypto.py", line 74, in <genexpr>
   return ''.join(secrets.choice(allowed_chars) for i in range(length))
 File "C:\Users\user\AppData\Local\Programs\Python\Python38\lib\random.py", line 288, in choice
   i = self._randbelow(len(seq))
TypeError: object of type 'int' has no len()

As I understand I should be able to set the length of an integer and set it as a numeric id to be stored each time a new product is created in the database.

My apologies if this question is stupid, but this is my very first question here and I searched and could not find a solution for this.


Solution

  • It is worth mentioning you are passing an int type to a string method. Which is what the error is indicating.

    Using randint will return an integer and is best suited for this use case. One way to do this is by overriding the model save method:

    from random import randint
    
    class Product(models.Model):
        title = models.CharField(max_length=255)
        slug = models.SlugField(max_length=255)
        category = models.ForeignKey(Category, related_name='products', on_delete=models.CASCADE)
        product_id = models.IntegerField(null=True, Blank=True)  # Max length 5, numerals only
        description = models.TextField(blank=True, null=True)
        price = models.FloatField()
    
        def save(self, **kwargs):
            if not self.product_id:
                self.product_id = randint(10000, 99999)
            return super(Product, self).save(**kwargs)