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=…)
.