Search code examples
djangodjango-viewsone-time-password

reuse of views in django



I am creating a django site where I use an OTP (one time password) to validate user data when logging in. So I have a view in which I manage the login and one that emails the otp, provides the form, checks that the otp is correct and redirects the user to the homepage. Now I would like to reuse the otp view in other situations as well (e.g. password change or recovery). How can I use a view as if it were a normal function, in the sense of calling it from within another view, rendering a template and returning a value to the calling view?
Thanks in advance

Solution

  • Make it a decorator. E.g. the @login_required decorator you may have used is backed by user_passes_test(); your @otp_required decorator could have more logic and only defer to the original view function once your OTP magic passes.

    Something like this, as semi-pseudocode. There's no special magic to it, really – the view function decorator simply wraps the view, so it can do whatever a view can.

    from functools import wraps
    
    
    class OtpView(views.FormView):
        pass
    
    
    def requires_otp(view_func):
        @wraps(view_func)
        def _wrapped_view(request, *args, **kwargs):
            if not has_valid_otp_for_request(request):
                return OtpView.as_view()(request)
            return view_func(request, *args, **kwargs)
        return _wrapped_view
    
    # ...
    
    @requires_otp
    def my_view(...):
       pass
    
    # or for CBVs:
    
    ... requires_otp(MyView.as_view()) ...