In the Django 2.2 docs , it states the following :
"is_active " is a 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.
My question is this, If I had a website, and I gave my users the ability to delete their own accounts by following this practice, wouldn't my database be filled with non-active accounts once my website gains a bit of traffic?
What would be the best method to letting users ( without staff or super user status ) on your website delete their own accounts properly in Django 2.2 ?
Thank you in Advance for any Help
My question is this, If I had a website, and I gave my users the ability to delete their own accounts by following this practice, wouldn't my database be filled with non-active accounts once my website gains a bit of traffic?
Eventually, yes. The question is, Why is that a problem?. Databases normally construct indexes on primary keys, so that means that it can often retrieve the user of a given post object often efficiently, even if there is a certain amount of "dead data".
The main problem with deleting a user is that there are often triggers that will remove all the related data. Indeed, imagine that you have a Post
model:
from django.conf import settings
class Post(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
This means that if you delete a user, it will remove all Post
objects where that user is the author, and not only for Post
s of course, but everything you link to that user with a CASCADE
trigger. This might not be the intended effect. Often you want to keep the data the user has constructed, unless for example the user (explicitly) asks this.
You can define views to let people delete their account, either as a "soft" delete (with .is_active
set to False
), or a "hard" delete (remove the object, and let the triggers ripple). You can make views like:
# soft delete
from django.contrib.auth import logout as auth_logout, get_user_model
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
@login_required
@require_http_method(['POST'])
def remove_account(request):
user_pk = request.user.pk
auth_logout(request)
User = get_user_model()
User.objects.filter(pk=user_pk).update(is_active=False)
# …
# return HTTP response
or a hard delete:
# hard delete
from django.contrib.auth import logout as auth_logout, get_user_model
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
@login_required
@require_http_method(['POST'])
def remove_account(request):
user_pk = request.user.pk
auth_logout(request)
User = get_user_model()
User.objects.filter(pk=user_pk).delete()
# …
# return HTTP response
and in the template a button to remove the account:
<form method="post" action="{% url 'name-of-delete-view' %}">
{% csrf_token %}
<button type="submit">delete account</button>
</form>
with name-of-delete-view
the name you have given to the view in the path(…, name=…)
or re_path(…, name=…)
.