Django: Preserve user data after account deletion in e-commerce orders

Hey everyone! I’m working on an e-commerce project using Django and I’ve hit a snag. I want to keep customer info for orders even if they delete their account. But I’m not sure how to do this without duplicating data.

Here’s what I’ve got so far:

from django.contrib.auth import get_user_model
from django.db import models

class Purchase(models.Model):
    buyer_email = models.EmailField()
    buyer_first = models.CharField(max_length=50)
    buyer_last = models.CharField(max_length=50)
    buyer = models.ForeignKey(get_user_model(), null=True, on_delete=models.SET_NULL)

    def prep_save(self):
        if self.buyer:
            self.buyer_email = self.buyer.email
            self.buyer_first = self.buyer.first_name
            self.buyer_last = self.buyer.last_name

    def save(self, *args, **kwargs):
        self.prep_save()
        super().save(*args, **kwargs)

This works, but it feels like I’m repeating myself. Is there a better way to do this? Or do I just have to accept the duplication? Any tips would be awesome. Thanks!

Your approach is on the right track, but there’s room for improvement. Consider implementing a custom user model that includes all necessary fields for orders. This way, you can set on_delete=models.SET_DEFAULT for the ForeignKey in your Purchase model, preserving order data even after account deletion. You’d need to create a default ‘deleted user’ instance to handle this scenario. This method maintains data integrity without duplication and aligns with Django best practices for user management in e-commerce applications. It’s a more scalable solution that’ll serve you well as your project grows.

Hey Mike_Energetic! That’s a great question you’ve got there. I’ve been working with Django for a while now, and I’ve run into similar issues before. Have you considered using a separate Customer model that’s not tied to the User model?

Something like this might work:

class Customer(models.Model):
    email = models.EmailField(unique=True)
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    user = models.OneToOneField(get_user_model(), null=True, on_delete=models.SET_NULL)

class Purchase(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.PROTECT)
    # other fields...

This way, even if a user deletes their account, you still keep the customer info for orders. What do you think about this approach? Have you tried something similar before?

Also, I’m curious - what made you choose Django for your e-commerce project? Are you finding it suits your needs well so far?

yo mike, try using a post_save signal on purchase save.
this copies buyer data if exists and avoids code duplication.
whatcha think?