I decided to use the simplest captcha django-simple-captcha in the project and faced with the fact that it is not a random code that for some reason always produces the same values as on the host and on the host. And for generation I tried all possible ways.
def random_char_challenge(): chars,ret = list(u'abcdefghijklmnopqrstuvwxyz'), u'' random.shuffle(chars) for i in range(settings.CAPTCHA_LENGTH): ret += random.choice(chars) random.shuffle(chars) return ret.upper(),ret def myrandom_char_challenge(): random.shuffle(settings.my_alphabet) ret = u'' for ch in random.sample(settings.my_alphabet,settings.CAPTCHA_LENGTH): ret += ch return ret.upper(),ret
settings.my_alphabet set in settings to always have mixed values. it helped but not much ....
Can a bug in the use of a captcha?
I use it like this
class FlatForm(forms.ModelForm): captcha = CaptchaField() class Meta: model = Flats exclude = ('user', 'views', 'added', 'unlimited', 'add1', 'objtype','key')
here is the result on the site
Of course, I can rewrite the captcha code, and in order not to create an object in the database, it was checked for uniqueness, but it somehow strangely happens with random. these are project settings
INSTALLED_APPS = ( ... 'captcha', ) #urls.py url(r'^captcha/', include('captcha.urls')),
these are captcha settings import os from django.conf import settings
CAPTCHA_FONT_PATH = getattr(settings,'CAPTCHA_FONT_PATH', os.path.normpath(os.path.join(os.path.dirname(__file__), '..', 'fonts/Vera.ttf'))) CAPTCHA_FONT_SIZE = getattr(settings,'CAPTCHA_FONT_SIZE', 24) CAPTCHA_LETTER_ROTATION = getattr(settings, 'CAPTCHA_LETTER_ROTATION', (-20,20)) CAPTCHA_BACKGROUND_COLOR = getattr(settings,'CAPTCHA_BACKGROUND_COLOR', '#ffffff') CAPTCHA_FOREGROUND_COLOR= getattr(settings,'CAPTCHA_FOREGROUND_COLOR', '#ae0033') CAPTCHA_CHALLENGE_FUNCT = getattr(settings,'CAPTCHA_CHALLENGE_FUNCT','captcha.helpers.myrandom_char_challenge') CAPTCHA_NOISE_FUNCTIONS = getattr(settings,'CAPTCHA_NOISE_FUNCTIONS', ('captcha.helpers.noise_arcs','captcha.helpers.noise_dots',)) CAPTCHA_FILTER_FUNCTIONS = getattr(settings,'CAPTCHA_FILTER_FUNCTIONS',('captcha.helpers.post_smooth',)) CAPTCHA_WORDS_DICTIONARY = getattr(settings,'CAPTCHA_WORDS_DICTIONARY', '/usr/share/dict/words') CAPTCHA_PUNCTUATION = getattr(settings, 'CAPTCHA_PUNCTUATION', '''_"',.;:-''') CAPTCHA_FLITE_PATH = getattr(settings,'CAPTCHA_FLITE_PATH',None) CAPTCHA_TIMEOUT = getattr(settings, 'CAPTCHA_TIMEOUT', 4) # Minutes CAPTCHA_LENGTH = int(getattr(settings, 'CAPTCHA_LENGTH', 5)) # Chars CAPTCHA_IMAGE_BEFORE_FIELD = getattr(settings,'CAPTCHA_IMAGE_BEFORE_FIELD', True) CAPTCHA_DICTIONARY_MIN_LENGTH = getattr(settings,'CAPTCHA_DICTIONARY_MIN_LENGTH', 0) CAPTCHA_DICTIONARY_MAX_LENGTH = getattr(settings,'CAPTCHA_DICTIONARY_MAX_LENGTH', 99) if CAPTCHA_IMAGE_BEFORE_FIELD: CAPTCHA_OUTPUT_FORMAT = getattr(settings,'CAPTCHA_OUTPUT_FORMAT', u'%(image)s %(hidden_field)s %(text_field)s') else: CAPTCHA_OUTPUT_FORMAT = getattr(settings,'CAPTCHA_OUTPUT_FORMAT', u'%(hidden_field)s %(text_field)s %(image)s') # Failsafe if CAPTCHA_DICTIONARY_MIN_LENGTH > CAPTCHA_DICTIONARY_MAX_LENGTH: CAPTCHA_DICTIONARY_MIN_LENGTH, CAPTCHA_DICTIONARY_MAX_LENGTH = CAPTCHA_DICTIONARY_MAX_LENGTH, CAPTCHA_DICTIONARY_MIN_LENGTH def _callable_from_string(string_or_callable): if callable(string_or_callable): return string_or_callable else: return getattr(__import__( '.'.join(string_or_callable.split('.')[:-1]), {}, {}, ['']), string_or_callable.split('.')[-1]) def get_challenge(): return _callable_from_string(CAPTCHA_CHALLENGE_FUNCT) def noise_functions(): if CAPTCHA_NOISE_FUNCTIONS: return map(_callable_from_string, CAPTCHA_NOISE_FUNCTIONS) return list() def filter_functions(): if CAPTCHA_FILTER_FUNCTIONS: return map(_callable_from_string, CAPTCHA_FILTER_FUNCTIONS) return list() my_alphabet = list(u'abcdefghijklmnopqrstuvwxyz')