Here is the function:
def generate_password():
alphabet = string.ascii_letters + string.digits + "!@#$%^&*()+=/.,"
return ''.join(secrets.choice(alphabet) for i in range(12))
I added this to a Django model, so that it is automatically called when creating a user, and automatically generates its password. This is the code in the model:
password = models.CharField(max_length=100, default=generate_password())
For some reason, creating 4 users is always going to create at least one duplicate password, if not two.
this is an example of the passwords generated by creating 7 users:
PpN(ky^tabgP
iIS@4gfe@7sc
6#oNlIH0MbQg
6#oNlIH0MbQg
iIS@4gfe@7sc
PpN(ky^tabgP
PpN(ky^tabgP
This approach was suggested by different people and documentation, yet it seems like this function is always cycling between only a few passwords, and keeps repeating them.
Can anyone help me understand why and how to avoid it?
Django needs to be restarted some times so adding passwords to a set is not convenient.
The problem is here.
password = models.CharField(max_length=100, default=generate_password())
It must be(without parentheses)
password = models.CharField(max_length=100, default=generate_password)
because you need to pass a callable object as default
argument and it will be called by django when every time a new object is created.
But that's not the case with your current code. Since you are using parentheses ()
, the function generate_password
immediately gets invoked and return value gets assigned to the default
.