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))