pythondjangodjango-registration

Django-registration: How to allow user delete their account?


I have a simple website where users can register in order to have access to private content and to receive a newsletter. I have used django-registration for user registration and authentication, and used some HTML templates from here.

The whole system is working (login, logout, password recovery, etc.) but I realized that user cannot delete their account from the website. Is there a plugin designed for this, or how to extend the registration classes to do that? By deleting, I'd prefer a real suppression, not just making the user inactive.


Solution

  • You can do something like this:

    def delete_user(request, username):
        context = {}
        
        try:
            u = User.objects.get(username=username)
            u.delete()
            context['msg'] = 'The user is deleted.'       
        except User.DoesNotExist: 
            context['msg'] = 'User does not exist.'
        except Exception as e: 
            context['msg'] = e.message
    
        return render(request, 'template.html', context=context) 
    

    And have a url pattern like:

    url(r'^delete/(?P<username>[\w|\W.-]+)/$', views.delete_user, name='delete-user')
    

    This will do the work. It will delete a user by given username.

    But, as the docs say:

    is_active

    Boolean. Designates whether this user account should be considered active. We recommend that you set this flag to False instead of deleting accounts; that way, if your applications have any foreign keys to users, the foreign keys won’t break.

    It is a better approach to set the user as inactive instead of deleting it totally from the database, because the foreign keys will break.

    So you can simply do:

    def delete_user(request, username):
        context = {}
    
        try:
            user = User.object.get(username=username)
            user.is_active = False
            user.save()
            context['msg'] = 'Profile successfully disabled.'
        except User.DoesNotExist:
            # ...
        except Exception as e:
            # ...
        
        # ...
    

    And as now everyone can access this view, you must add some permissions. A straightforward approach will be to override the built-in @user_passes_test decorator:

    @user_passes_test(lambda u: u.is_staff, login_url=reverse_lazy('login'))
    def delete_user(request, username):
        # ...