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') 
  • Please show me how you hooked up in the settings. - metazet
  • Updated. In general, all this is strange, namely random randomly random randomly the same number in the debugger. - stasych

1 answer 1

Try explicitly specifying your handler function in settings.py:

 CAPTCHA_CHALLENGE_FUNCT = 'path.to.myrandom_char_challenge' 

I used exactly the same way as you did - I only built the form not on the basis of the model, but in a couple of fields. Maybe this is the problem? Although I doubt it.

  • Yes, it's definitely not the settings, I already registered the function when exporting the generation. There is a crazy idea that it can really matter in the model ... although the key can somehow be cached and I just get the same key when the page is refreshed ... just by whom and how it is cached. Killed with this question nafig =) - stasych
  • Oh, by the way! Do you output form fields through template tags or manually score by ID? - metazet
  • through template tags ... although there is a large form, maybe I’m the only one, and I’m scored through id =) but do you think there is a difference? - stasych
  • The difference is big, if the captcha is just copied, then the hashes were copied, which means it will be generated different, but the same will be displayed and validation will not work. I myself faced this when I first fastened this captcha. Check the captcha hashes in the page code. If the hash is always the same and the form is valid - it means you have a problem with the generator function, otherwise - dig in the direction of template tags, you can output something "crooked";) Good luck! - metazet