Skip to content

Commit 3252641

Browse files
committed
Allow forms to be overriden (closes #511)
1 parent 5edc5c8 commit 3252641

File tree

7 files changed

+72
-1
lines changed

7 files changed

+72
-1
lines changed

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2014-07-22 Raymond Penners <raymond.penners@intenct.nl>
2+
3+
* All forms are now pluggable via a new setting:
4+
`(SOCIAL)ACCOUNT_FORMS`.
5+
16
2014-07-05 Raymond Penners <raymond.penners@intenct.nl>
27

38
* James Thompson contributed Windows Live support, thanks!

allauth/account/app_settings.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,10 @@ def SESSION_REMEMBER(self):
222222
"""
223223
return self._setting('SESSION_REMEMBER', None)
224224

225+
@property
226+
def FORMS(self):
227+
return self._setting('FORMS', {})
228+
225229

226230
# Ugly? Guido recommends this himself ...
227231
# http://mail.python.org/pipermail/python-ideas/2012-May/014969.html

allauth/account/views.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
from django.shortcuts import redirect
1414

1515
from ..exceptions import ImmediateHttpResponse
16-
from ..utils import get_user_model
16+
from ..utils import get_user_model, get_form_class
1717

1818
from .utils import (get_next_redirect_url, complete_signup,
1919
get_login_redirect_url, perform_login,
@@ -89,6 +89,9 @@ class LoginView(RedirectAuthenticatedUserMixin,
8989
success_url = None
9090
redirect_field_name = "next"
9191

92+
def get_form_class(self):
93+
return get_form_class(app_settings.FORMS, 'login', self.form_class)
94+
9295
def form_valid(self, form):
9396
success_url = self.get_success_url()
9497
return form.login(self.request, redirect_url=success_url)
@@ -150,6 +153,9 @@ class SignupView(RedirectAuthenticatedUserMixin, CloseableSignupMixin,
150153
redirect_field_name = "next"
151154
success_url = None
152155

156+
def get_form_class(self):
157+
return get_form_class(app_settings.FORMS, 'signup', self.form_class)
158+
153159
def get_success_url(self):
154160
# Explicitly passed ?next= URL takes precedence
155161
ret = (get_next_redirect_url(self.request,
@@ -281,6 +287,9 @@ class EmailView(FormView):
281287
form_class = AddEmailForm
282288
success_url = reverse_lazy('account_email')
283289

290+
def get_form_class(self):
291+
return get_form_class(app_settings.FORMS, 'add_email', self.form_class)
292+
284293
def dispatch(self, request, *args, **kwargs):
285294
sync_user_email_addresses(request.user)
286295
return super(EmailView, self).dispatch(request, *args, **kwargs)
@@ -420,6 +429,11 @@ class PasswordChangeView(FormView):
420429
form_class = ChangePasswordForm
421430
success_url = reverse_lazy("account_change_password")
422431

432+
def get_form_class(self):
433+
return get_form_class(app_settings.FORMS,
434+
'change_password',
435+
self.form_class)
436+
423437
def dispatch(self, request, *args, **kwargs):
424438
if not request.user.has_usable_password():
425439
return HttpResponseRedirect(reverse('account_set_password'))
@@ -456,6 +470,11 @@ class PasswordSetView(FormView):
456470
form_class = SetPasswordForm
457471
success_url = reverse_lazy("account_set_password")
458472

473+
def get_form_class(self):
474+
return get_form_class(app_settings.FORMS,
475+
'set_password',
476+
self.form_class)
477+
459478
def dispatch(self, request, *args, **kwargs):
460479
if request.user.has_usable_password():
461480
return HttpResponseRedirect(reverse('account_change_password'))
@@ -490,6 +509,11 @@ class PasswordResetView(FormView):
490509
form_class = ResetPasswordForm
491510
success_url = reverse_lazy("account_reset_password_done")
492511

512+
def get_form_class(self):
513+
return get_form_class(app_settings.FORMS,
514+
'reset_password',
515+
self.form_class)
516+
493517
def form_valid(self, form):
494518
form.save()
495519
return super(PasswordResetView, self).form_valid(form)
@@ -516,6 +540,11 @@ class PasswordResetFromKeyView(FormView):
516540
token_generator = default_token_generator
517541
success_url = reverse_lazy("account_reset_password_from_key_done")
518542

543+
def get_form_class(self):
544+
return get_form_class(app_settings.FORMS,
545+
'reset_password_from_key',
546+
self.form_class)
547+
519548
def _get_user(self, uidb36):
520549
# pull out user
521550
try:

allauth/socialaccount/app_settings.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ def ADAPTER(self):
5959
'allauth.socialaccount.adapter'
6060
'.DefaultSocialAccountAdapter')
6161

62+
@property
63+
def FORMS(self):
64+
return self._setting('FORMS', {})
65+
66+
6267
# Ugly? Guido recommends this himself ...
6368
# http://mail.python.org/pipermail/python-ideas/2012-May/014969.html
6469
import sys

allauth/socialaccount/views.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,25 @@
99
from ..account.views import (CloseableSignupMixin,
1010
RedirectAuthenticatedUserMixin)
1111
from ..account.adapter import get_adapter as get_account_adapter
12+
from ..utils import get_form_class
13+
1214
from .adapter import get_adapter
1315
from .models import SocialLogin
1416
from .forms import DisconnectForm, SignupForm
1517
from . import helpers
18+
from . import app_settings
1619

1720

1821
class SignupView(RedirectAuthenticatedUserMixin, CloseableSignupMixin,
1922
FormView):
2023
form_class = SignupForm
2124
template_name = 'socialaccount/signup.html'
2225

26+
def get_form_class(self):
27+
return get_form_class(app_settings.FORMS,
28+
'signup',
29+
self.form_class)
30+
2331
def dispatch(self, request, *args, **kwargs):
2432
self.sociallogin = None
2533
data = request.session.get('socialaccount_sociallogin')
@@ -73,6 +81,11 @@ class ConnectionsView(FormView):
7381
form_class = DisconnectForm
7482
success_url = reverse_lazy("socialaccount_connections")
7583

84+
def get_form_class(self):
85+
return get_form_class(app_settings.FORMS,
86+
'disconnect',
87+
self.form_class)
88+
7689
def get_form_kwargs(self):
7790
kwargs = super(ConnectionsView, self).get_form_kwargs()
7891
kwargs["request"] = self.request

allauth/utils.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,3 +188,10 @@ def build_absolute_uri(request, location, protocol=None):
188188
if protocol:
189189
uri = protocol + ':' + uri.partition(':')[2]
190190
return uri
191+
192+
193+
def get_form_class(forms, form_id, default_form):
194+
form_class = forms.get(form_id, default_form)
195+
if isinstance(form_class, six.string_types):
196+
form_class = import_attribute(form_class)
197+
return form_class

docs/configuration.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ ACCOUNT_DEFAULT_HTTP_PROTOCOL = (="http")
4848
password forgotten procedure. Note that this is a default only --
4949
see the section on HTTPS for more information.
5050

51+
ACCOUNT_FORMS (={})
52+
Used to override forms, for example:
53+
`{'login': 'myapp.forms.LoginForm'}`
54+
5155
ACCOUNT_LOGOUT_ON_GET (=False)
5256
Determines whether or not the user is automatically logged out by a
5357
mere GET request. See documentation for the `LogoutView` for
@@ -136,5 +140,9 @@ SOCIALACCOUNT_EMAIL_REQUIRED (=ACCOUNT_EMAIL_REQUIRED)
136140
SOCIALACCOUNT_EMAIL_VERIFICATION (=ACCOUNT_EMAIL_VERIFICATION)
137141
As `ACCOUNT_EMAIL_VERIFICATION`, but for social accounts.
138142

143+
SOCIALACCOUNT_FORMS (={})
144+
Used to override forms, for example:
145+
`{'signup': 'myapp.forms.SignupForm'}`
146+
139147
SOCIALACCOUNT_PROVIDERS (= dict)
140148
Dictionary containing provider specific settings.

0 commit comments

Comments
 (0)