Reputation: 1771
I have an python/django application with simple captcha. Simple captcha is appeared according to some algorithm.
There are two almost same constructors. The difference is just in inheritance. How to avoid code duplication?
class PostCaptchaForm(PostForm):
captcha = CaptchaField()
def __init__(self, *args, **kwargs):
self.request = kwargs['request']
del kwargs['request']
super(PostCaptchaForm, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(PostCaptchaForm, self).clean()
success = self.is_valid()
utils.update_captcha_access(self.request, success)
if success:
return cleaned_data
else:
raise forms.ValidationError("captcha validation failed")
class ThreadCaptchaForm(ThreadForm):
captcha = CaptchaField()
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super(ThreadCaptchaForm, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(ThreadCaptchaForm, self).clean()
success = self.is_valid()
utils.update_captcha_access(self.request, success)
if success:
return cleaned_data
else:
raise forms.ValidationError("captcha validation failed")
Upvotes: 2
Views: 97
Reputation: 12195
I'd do it with multiple inheritance, with a base captcha form as a mixin, to be used alongside ThreadForm or PostForm
class CaptchaFormBase(forms.Form): # or forms.ModelForm, if appropriate
captcha = CaptchaField()
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
# this is the same as assigning to self request then deleting the key
super(CaptchaFormBase, self).__init__(*args, **kwargs)
def clean(self):
cleaned_data = super(CaptchaFormBase, self).clean()
success = self.is_valid()
utils.update_captcha_access(self.request, success)
if not success:
# this will put things in non_field_errors, you may want to put it in self.errors['captcha']
raise forms.ValidationError("Captcha validation failed")
# always make it easy to see that you're returning cleaned_data
return self.cleaned_data
class PostCaptchaForm(PostForm, CaptchaFormBase):
pass
class ThreadCaptchaForm(ThreadForm, CaptchaFormBase):
pass
Upvotes: 3