OK, this is for anyone who needs to manually generate a Django password. I was faced with this problem because I needed to manually insert a new Django user in the database. So, how to take the desired plain text password and to convert it properly so that you can insert it in the “password” field of the auth_user table in the Django database?
To answer this question, I had to take a look at the way Django handles user passwords. Basically, I needed to look at the following Python files from Django repository: utils.py, utils/encoding.py, utils/functional.py.
I’ve grabbed just the functions that I needed and put them together in the following piece of code that you can use.
Just set the “raw_password” variable to the password you want to use. The code uses sha1 as the encryption algorithm. I suppose that it will work for md5 too. Just set the “algorithm” variable to “md5″.
def get_random_string(length=12, allowed_chars='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'):
"""
Returns a random string of length characters from the set of a-z, A-Z, 0-9
for use as a salt.
The default length of 12 with the a-z, A-Z, 0-9 character set returns
a 71-bit salt. log_2((26+26+10)^12) =~ 71 bits
"""
import random
try:
random = random.SystemRandom()
except NotImplementedError:
pass
return ''.join([random.choice(allowed_chars) for i in range(length)])
class Promise(object):
"""
This is just a base class for the proxy class created in
the closure of the lazy function. It can be used to recognize
promises in code.
"""
pass
def smart_str(s, encoding='utf-8', strings_only=False, errors='strict'):
"""
Returns a bytestring version of 's', encoded as specified in 'encoding'.
If strings_only is True, don't convert (some) non-string-like objects.
"""
if strings_only and isinstance(s, (types.NoneType, int)):
return s
if isinstance(s, Promise):
return unicode(s).encode(encoding, errors)
elif not isinstance(s, basestring):
try:
return str(s)
except UnicodeEncodeError:
if isinstance(s, Exception):
# An Exception subclass containing non-ASCII data that doesn't
# know how to print itself properly. We shouldn't raise a
# further exception.
return ' '.join([smart_str(arg, encoding, strings_only,
errors) for arg in s])
return unicode(s).encode(encoding, errors)
elif isinstance(s, unicode):
return s.encode(encoding, errors)
elif s and encoding != 'utf-8':
return s.decode('utf-8', errors).encode(encoding, errors)
else:
return s
def get_hexdigest(algorithm, salt, raw_password):
"""
Returns a string of the hexdigest of the given plaintext password and salt
using the given algorithm ('md5', 'sha1' or 'crypt').
"""
raw_password, salt = smart_str(raw_password), smart_str(salt)
if algorithm == 'crypt':
try:
import crypt
except ImportError:
raise ValueError('"crypt" password algorithm not supported in this environment')
return crypt.crypt(raw_password, salt)
if algorithm == 'md5':
return hashlib.md5(salt + raw_password).hexdigest()
elif algorithm == 'sha1':
return hashlib.sha1(salt + raw_password).hexdigest()
raise ValueError("Got unknown password algorithm type in password.")
import hashlib
algorithm='sha1'
salt=get_random_string()
raw_password='YOUR_PASSWORD_HERE'
raw_password, salt = smart_str(raw_password), smart_str(salt)
hsh = get_hexdigest(algorithm, salt, raw_password)
'%s$%s$%s' % (algorithm, salt, hsh)


Thanks for posting this – I had to do the same thing today and you saved me some time!