I'm using a custom backend (subclassed django-registration's SimpleBackend).
I override the register()
method, because I need to do some processing during the registration (for example, communicate with external services).
In case the registration fails, can I tell the registration form an error occurred?
Does this need to be implemented at the form validation level?
As another example, a database error could happen at user creation. How can the registration gracefully fail?
EDIT: Here is my subclass of SimpleBackend:
class MySimpleBackend(SimpleBackend):
def register(self, request, **kwargs):
username, email, password = kwargs['username'], kwargs['email'], kwargs['password1']
#
# Make a call to some external API, for example
retval = api_call_to_somewhere()
if retval is False:
# Request failed: display some error message on registration form
return something
# OR
raise some_other
# Rest of code is the same as django-registration
User.objects.create_user(username, email, password)
# authenticate() always has to be called before login(), and
# will return the user we just created.
new_user = authenticate(username=username, password=password)
login(request, new_user)
signals.user_registered.send(sender=self.__class__,
user=new_user,
request=request)
return new_user
I ended up customizing django-registration's register
view, from registration.views
(not to be confused with SimpleBackend.register
method)
The original view calls backend.register()
if form.is_valid()
, and then redirects to the success URL, so it assumes a user is created in backend.register()
, not catching any exception.
Adding my own code to catch exceptions, I can raise errors on backend.register()
and display them to the user, as a form error.
Below is the code as it appears on django-registration\registration\views
, in the middle of register
function, with the lines I added:
if request.method == 'POST':
form = form_class(data=request.POST, files=request.FILES)
if form.is_valid():
try: # added this line
new_user = backend.register(request, **form.cleaned_data)
if success_url is None:
to, args, kwargs = backend.post_registration_redirect(request, new_user)
return redirect(to, *args, **kwargs)
else:
return redirect(success_url)
# added these 3 lines below
except Exception, err:
errors = form._errors.setdefault(NON_FIELD_ERRORS, ErrorList())
errors.append(err)