1

I have an Article model that allows admins to publish articles. Each article is assigned to a user that is creating this article.

I want to make sure that all articles will stay untouched even if I delete the author of this particular article. I chose on_delete=models.DO_NOTHING to be sure that nothing except user account will be removed but I am not quite sure that is the most effective way.

class Article(models.Model):
    id = models.AutoField(primary_key=True)
    author = models.ForeignKey(User, blank=True, null=True, on_delete=models.DO_NOTHING)
    title = models.CharField('Title', max_length=70, help_text='max 70 characters')
    body = models.TextField('Description')

Question

Should I use another option to use or DO_NOTHING is good enough. Obviously the most important to me is that author's name will be visible in the article after deletion and the article itself cannot be removed.

Adrian
  • 725
  • 4
  • 18
  • doesn't using this option create integrity issues in your database? because right now if you delete the user your article will be referencing to something that does not exist. – Mojtaba Apr 07 '22 at 11:36
  • 1
    actually I tried to remove user that created article and I get IntegrityError at /admin/user/user/ FOREIGN KEY constraint failed error – Adrian Apr 07 '22 at 11:41
  • you can check the answer again I added another solution if you have custom user model. – Mojtaba Apr 07 '22 at 11:58

3 Answers3

1

Basically the database table creates record in certain table and stores user info as I can see you are linking article model with user based on User model.

There can be two cases like if you want the article to remain in database even if you delete the author you will get article when the article gets displayed somewhere.

If you do Cascade delete it deletes article record when associated author gets delete.

If you do models.Protect you wont get access to delete article when you user is deleted.

coming to your very models.Do nothings is a bad idea since this would create integrity issues in your database (referencing an object that actually doesn't exist). SQL equivalent: NO ACTION

find more here.

lord stock
  • 1,191
  • 5
  • 32
  • so what is the best option if I want to keep deleted author's name and article? Because CASCADE and PROTECT will delete or inform me to delete everything before removing users? – Adrian Apr 07 '22 at 11:51
1

Best I can say is:

add another field called author_name.

now set the on_delete of your author to models.SET_NULL.

Add a custom save method to add the name of your user to author_name.

Add a property to your model named author_full_name in this property check if author is not null return user name and last name. if author is None return author_name.

This way when the article is saved user full name is saved on author_name. and if user is deleted you can use the author_name. but watch out for the custom save method it might add some issues if you don't check the user and it's deletion.


Edit: Another solution

If you have a custom user model you can a field to your users called is_deleted.

After your users delete their accounts just set this field to True and have the logic in your app to excludes deleted accounts.

this way your users won't be accessible to anyone but you can use them for the articles and foreign keys. (remember to tell your users that account deletion works this way or set a task to remove accounts after a while and set the field that I said above.)

Mojtaba
  • 583
  • 1
  • 5
  • 15
0

You just need to use CASCADE as below: on_delete=models.CASCADE

  • Thanks for the answer but Cascade will remove all articles that author has created and I want to keep them and keep the name and surname in the article – Adrian Apr 07 '22 at 19:21