Home > Software engineering >  Can't call .delete() on a user account instance in Django
Can't call .delete() on a user account instance in Django

Time:10-06

I am trying to set up a simple view to delete user accounts. However, for whatever reason it returns

Field 'id' expected a number but got 'deleted_user'.

and doesn't delete the instance.

# View

def delete_account(request, username):
    """
    Deletes the user account
    """
    user = Account.objects.get(username=username).delete()

    return redirect('pollboard')
# Model

class Account(AbstractBaseUser):

    email = models.EmailField(verbose_name='email', max_length=60, unique=True)
    username = models.CharField(max_length=40, unique=True)
    date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
    email_confirmed = models.BooleanField(default=False)
    last_login = models.DateTimeField(verbose_name='last login', auto_now=True)
    is_admin = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    profile_image = models.ImageField(max_length=255, upload_to=get_profile_image_filepath, null=True, blank=True, default=get_default_profile_image())
    hide_email = models.BooleanField(default=True)


class Poller(models.Model):
    """
    Main Model to describe Poller objects
    """
    created_on = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(Account, on_delete=models.SET('deleted_user'))
# Template

        <div class="delete-modal-buttons">
            <a href="{% url 'delete-account' username=user.username %}"><button class="delete-button" id="delete-account">Delete Account</button></a>
            <button class="delete-button" id="cancel-delete">Cancel</button>
        </div>
# Traceback

Environment:


Request Method: GET
Request URL: http://127.0.0.1:8000/dashboard/admin/delete-account/

Django Version: 3.2.7
Python Version: 3.9.6
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.humanize',
 'apps.core',
 'apps.pollinator',
 'apps.pollboard',
 'apps.userprofile',
 'tinymce']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 1823, in get_prep_value
    return int(value)

The above exception (invalid literal for int() with base 10: 'deleted_user') was the direct cause of the following exception:
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/jonas/PycharmProjects/poller/apps/userprofile/views.py", line 94, in delete_account
    user = Account.objects.get(username=username).delete()
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/base.py", line 954, in delete
    return collector.delete()
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/deletion.py", line 418, in delete
    query.update_batch([obj.pk for obj in instances],
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/sql/subqueries.py", line 75, in update_batch
    self.get_compiler(using).execute_sql(NO_RESULTS)
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1559, in execute_sql
    cursor = super().execute_sql(result_type)
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1162, in execute_sql
    sql, params = self.as_sql()
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/sql/compiler.py", line 1525, in as_sql
    val = field.get_db_prep_save(val, connection=self.connection)
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/fields/related.py", line 971, in get_db_prep_save
    return self.target_field.get_db_prep_save(value, connection=connection)
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 842, in get_db_prep_save
    return self.get_db_prep_value(value, connection=connection, prepared=False)
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 2486, in get_db_prep_value
    value = self.get_prep_value(value)
  File "/Users/jonas/PycharmProjects/poller/venv/lib/python3.9/site-packages/django/db/models/fields/__init__.py", line 1825, in get_prep_value
    raise e.__class__(

Exception Type: ValueError at /dashboard/admin/delete-account/
Exception Value: Field 'id' expected a number but got 'deleted_user'.

CodePudding user response:

You have specified on_delete=models.SET('deleted_user') for a foreign key pointing to your Account. This literally attempts to set the fields value to the string 'deleted_user'. The problem is that a foreign key is (mostly) the primary key of the related row of the other table, which by default is an integer. Hence setting it to a string makes no sense. Instead you can pass a function to models.SET which will get or create the placeholder user as described in the documentation:

def get_deleted_user():
    return Account.objects.get_or_create(username='deleted_user')[0]


class Poller(models.Model):
    """
    Main Model to describe Poller objects
    """
    created_on = models.DateTimeField(auto_now_add=True)
    created_by = models.ForeignKey(Account, on_delete=models.SET(get_deleted_user))
  • Related