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
CodePudding user response:
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
Usermodel by create a custom model likeCustomerthat inherits fromAbstractUser. This solution is the most flexible and easiest one, as you will have the same default DiangoUsermodel 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 issqlite) and delete all your migrations files, and do a freshpython manage.py makemigrationsafter implementing the mentioned solution. Also, this is a better approach if you want to add something likedeviceparameter 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
Customerthat extends theUsermodel by one-to-one relationship. Then, you can do the auto-creation and auto-save of theCustomermodel parallel with theUsermodel usingsignalsby 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.
