-1

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.

Xandro
  • 19
  • 1
  • 1
  • 6

1 Answers1

0

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.

Abdul Niyas P M
  • 18,035
  • 2
  • 25
  • 46
  • Thank you, I am testing this answer right now and will accept if it works as soon as I'm done. Could you elaborate a bit on this point for me please? I can't really understand the issue: "because you need to pass a callable object as default argument and it will be called every time a new object is created." I would understand if this resulted in an error, but since the function is being called, what is the difference that causes the passwords to repeat? – Xandro Feb 02 '23 at 10:29
  • @Xandro You can pass a string or a callable as an argument to `default`. Your current code is equivalent to passing a static string to `default` which will be using for all objects. But that's not the case if you pass a callable object. – Abdul Niyas P M Feb 02 '23 at 10:39
  • But in that case wouldn't the password always be the same? I'm still trying to understand – Xandro Feb 02 '23 at 12:54