How can a model be asigned to a User automatically?

Question:

So I am coding an e-commerce on Django in which in order to add items to cart, you need to be a customer. However, you log into the page as a user, which isnt the same. How can a customer be asigned to the User once it is created automatically? If it cannot be done automatically, then how can I insert a form to create the customer and for it to be related to the user?
I’ll insert some screenshots of the customer model and the views which matter.

this is the Customer model:

class Customer(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
name = models.CharField(max_length=200, null=True, blank=True)
email = models.CharField(max_length=200, null=True, blank=True)
device = models.CharField(max_length=200, null=True, blank=True)

def __str__(self):
    if self.name:
        name = self.name
    else:
        name = self.device
    return str(name)

here

this is the add to cart function in views.py

def cart(request):
if request.user.is_authenticated:
    customer = request.user.customer
    order, created = Order.objects.get_or_create(customer = customer, complete = False)
    items = order.orderitem_set.all()
else:
    items = []
    order = {'get_cart_total':0, 'get_cart_items':0}

context = {'items': items, 'order': order}
return render(request, 'store/cart.html', context)

And this is how I managed to delete items from the cart or more specifically the OrderItem model:

def deleteitem(request, id):
if request.method == "POST":
     
    

    item = OrderItem.objects.get(product = id)
    item.delete()
    return render(request, "store/deletecartitem.html", {'item': item})

if  OrderItem.objects.all == 0:
    customer =   customer = request.user.customer
    order = Order.objects.get(customer = customer)
    order.delete()

I could manually relate a customer to a user which has been already created from the Djnago admin , but it just wouldn’t be eficient. I’d like that when a user is registered, a customer is asigned to it automatically. Thank
you

Asked By: Mateo Doherty

||

Answers:

This is a trivial question about Django User model extension. You can understand more if you searched about Best practices to extend Django User model.

But generally, there are two common approaches that most of developers do:

  • Extending the User model by create a custom model like Customer that inherits from AbstractUser. This solution is the most flexible and easiest one, as you will have the same default Diango User model but with extra fields that you can add easily ongoing anytime through your development. If you like this approach and fits with your business case, you have to do it from the very beginning of development. Or, if you don’t care about the old migrations, you can delete your database (if it is sqlite) and delete all your migrations files, and do a fresh python manage.py makemigrations after implementing the mentioned solution. Also, this is a better approach if you want to add something like device parameter that you want your user to add it directly while registration.

AbstractUser approach:

from django.contrib.auth.models import AbstractUser

class Customer(AbstractUser):
    device = models.CharField(max_length=200, blank=True)
  • The second approach is nearly what you did, but it needs more custom work (and surely depends on your business case). It is about having a new model like Customer that extends the User model by one-to-one relationship. Then, you can do the auto-creation and auto-save of the Customer model parallel with the User model using signals by doing the below

Your approach:

class Customer(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    device = models.CharField(max_length=200, blank=True)

@receiver(post_save, sender=User)
def create_user_customer(sender, instance, created, **kwargs):
    if created:
        Customer.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_customer(sender, instance, **kwargs):
    instance.customer.save()

But in this case, the user will have to update his customer parameters later like device parameter.

Answered By: Yasser Mohsen
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.