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
User
model by create a custom model likeCustomer
that inherits fromAbstractUser
. This solution is the most flexible and easiest one, as you will have the same default DiangoUser
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 issqlite
) and delete all your migrations files, and do a freshpython manage.py makemigrations
after implementing the mentioned solution. Also, this is a better approach if you want to add something likedevice
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 theUser
model by one-to-one relationship. Then, you can do the auto-creation and auto-save of theCustomer
model parallel with theUser
model usingsignals
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.