I am trying to create cart using django but i am getting this error. while I try to check that the user is authenticated or no i used customer = request.user.customer but it says user has no attribute customer
Here is my views.py
def cart(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = OrderModel.objects.get_or_create(customer=customer, complete=False)
items = order.orderitem_set.all()
else:
items = []
context = {}
return render(request, 'Home/cart.html', context)
here is my models.py
class CustomerModel(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE, null=True, blank=True, default='')
customer_name = models.CharField(max_length=1000, null=True)
customer_phone = models.CharField(max_length=20, null=True)
def __str__(self):
return self.customer_name
class OrderModel(models.Model):
customer = models.ForeignKey(CustomerModel, on_delete=models.SET_NULL, null=True, blank=True)
order_date = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False,null=True,blank=True)
transaction_id = models.CharField(max_length=1000, null=True)
def __str__(self):
return str(self.id)
class OrderItem(models.Model):
product = models.ForeignKey(ProductModel, on_delete=models.SET_NULL, null=True, blank=True)
order = models.ForeignKey(OrderModel, on_delete=models.SET_NULL, null=True, blank=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
class Address(models.Model):
customer = models.ForeignKey(CustomerModel, on_delete=models.SET_NULL, null=True, blank=True)
order = models.ForeignKey(OrderModel, on_delete=models.SET_NULL, null=True, blank=True)
address = models.CharField(max_length=10000)
city = models.CharField(max_length=1000)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.address
I am stuck here and cant understand what to do.
I think changing the line customer = request.user.customer to customer = request.user.customermodel may solve your problem. If you want to use customer = request.user.customer add related name to your CustomerModel's field:
user = models.OneToOneField(User, on_delete = models.CASCADE, null=True, blank=True, default='', related_name='customer')
Note: Make sure that your user object has a related profile.
For example add an extra condition to your codes like following:
if hasattr(request.user, 'customer'): # If you have related name otherwise use customermodel
customer = request.user.customer
else:
# Return a proper message here
Because if your user object has no related profile this line of code will raise RelatedObjectDoesNotExist error type.
For the user field of the CustomerModel, you must set "related_name" and "related_query_name" to "customer":
user = models.OneToOneField(User, on_delete = models.CASCADE, null=True, blank=True, default='', related_name='customer', related_query_name='customer')
You have to set the "related_name" parameter in your CustomerModel customer field for reverse access
user = models.OneToOneField(User, related_name="user", on_delete = models.CASCADE, null=True, blank=True, default='')
if you don't set the related name django will generate field name + "_set" for the access (user_set in your example)
Related
I am working on a Django project which is something similar to Fiverr in its working. I have used abstractuser where there is a buyer and seller. The seller creates a gig then the buyer will go through the gig before placing an order. My issue is how to get the seller and place him in the order that the buyer will create from reading the gig. Currently I am using the system whereby the buyer will have to manually choose a gig from a list, which I think is not effective.
Here is my Models.py
`class User(AbstractUser):
is_buyer=models.BooleanField(default=False)
is_seller=models.BooleanField(default=False)
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(default='avatar.jpg', null=True, blank=True)
about = models.CharField(max_length=100)
def __str__(self):
return self.user.username
class Gig(models.Model):
seller = models.ForeignKey(Profile, on_delete = models.CASCADE, null=False, blank=False)
category = models.ForeignKey('Category', on_delete = models.CASCADE, null=False, blank=False)
title = models.CharField(max_length=500, null=True, blank=True)
description = models.CharField(max_length=500, null=True, blank=True)
gig_id = models.UUIDField(default=uuid.uuid4, primary_key=True, unique=True, editable=False)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Order(models.Model):
buyer = models.ForeignKey(Profile, on_delete=models.CASCADE, null=False, blank=False)
seller = models.ForeignKey(Gig, on_delete=models.CASCADE, related_name='+', null=False, blank=False)
title = models.CharField(max_length=500, null=True, blank=True)
description = models.CharField(max_length=500)
amount = models.IntegerField(max_length=50, blank=False)
is_ordered = models.BooleanField(default=False)
order_id = models.UUIDField(default=uuid.uuid4, unique=True, db_index=True, editable=False)
slug = models.SlugField(null=True)
def __str__(self):
return self.title`
And views.py where I am getting the submissions;
def createOrder(request):
profile = request.user.profile
form = CreateOrderForm()
if request.method == 'POST':
form = CreateOrderForm(request.POST, request.FILES)
if form.is_valid:
order = form.save(commit=False)
order.buyer = profile
order.save()
# form.save()
messages.info(request, 'Order Succesfully Created')
return redirect('create_order')
else:
messages.error(request, 'Order Not Created! Try Again Later')
context = {'form':form}
return render(request, 'users/create_order.html', context)
Any help will he highly appreciated.
how do I make it better for the website operator to process the order, can we have each orderitem and shippingaddress associated with the order to be under each "Order" in the admin panel? for example when someone clicks on an Order, he sees the Order data and he's able to scroll and also see the orderitem, and shipping address, would really appreciate your help, thx!
models.py
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False)
transaction_id = models.CharField(max_length=100, null=True)
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, blank=True, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True)
quantity = models.IntegerField(default=0)
date_added = models.DateTimeField(auto_now_add=True)
status = models.CharField(max_length=40, choices=STATUS_CHOICES, default="Order Placed")
tracking_no = models.CharField(max_length=300, null=True, blank=True)
class ShippingAddress(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, blank=True, null=True)
address_one = models.CharField(max_length=200)
city = models.CharField(max_length=200)
country = models.CharField(max_length=300)
zipcode = models.CharField(max_length=200)
date_added = models.DateTimeField(auto_now_add=True)
what it looks like rn:
admin.py
admin.site.register(Order, OrderAdmin)
admin.site.register(OrderItem, OrderItemAdmin)
admin.site.register(ShippingAddress, ShippingAddressAdmin)
This would be a solution which works for you
class OrderItemAdmin(admin.StackedInline):
model = OrderItem
class ShippingAddressAdmin(admin.StackedInline):
model = ShippingAddress
class OrderAdmin(admin.ModelAdmin):
inlines = [OrderItemAdmin, ShippingAddressAdmin]
admin.site.register(Order, OrderAdmin)
This is well documented here: https://docs.djangoproject.com/en/stable/ref/contrib/admin/#inlinemodeladmin-objects
I have this models:
Models:
class User(models.Model):
name = models.CharField(max_length=255, null=True, blank=True, verbose_name='Name')
class Grad(models.Model):
grad = models.CharField(max_length=255, null=True, blank=True, verbose_name='Grad')
order = models.PositiveIntegerField(max_length=255, null=True, blank=True, verbose_name='Order')
class Number(models.Model):
user = models.ForeignKey(User, null=True, blank=True, verbose_name='User', on_delete=models.CASCADE)
grad = models.ForeignKey(Grad, null=True, blank=True, verbose_name='Grad', on_delete=models.CASCADE)
View:
user_numbers = Number.objects.all()
Get example:
But i want only get the highest order grad value to each user:
Thank you in advance!
You can annotate values you need:
from django.db.models import Max
# ...
# In your view:
data = Number.objects.values('user__name').annotate(
order=Max('grad__order'),
grad='grad__grad',
)
user_numbers = data.all()
Hi I'm building a Webshop with a cart and checkout function. And I want to save data into a database.
Here are my models:
This is the model I want to save the data in:
class MessageItem(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
mItem = models.CharField(max_length=255, null=True)
mQuantity = models.CharField(max_length=255, null=True) # Could also be an Integer!
mOrderItem = models.CharField(max_length=255, null=True)
After I did that I want to call the data in another view and pass it into a sendmail() message variable. Does anyone know how I could do that?
Here are my other models:
class Customer(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200)
class Product(models.Model):
name = models.CharField(max_length=200, null=True)
price = models.FloatField()
digital = models.BooleanField(default=False, null=True, blank=False) # Nicht nötig
image = models.ImageField(null=True, blank=True)
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False, null=True, blank=False)
transaction_id = models.CharField(max_length=200, null=True)
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
Here is my View: I Want to save: item.product.name, item.quantity and items into the model.
#login_required(login_url='login')
def cart(request):
# If user logged in or not (Handling orders in cart)
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()
cartItems = order.get_cart_items
for item in items:
SMES = item.product.name, str(item.quantity), items
print(SMES)
context = {'items': items, 'order': order, 'cartItems': cartItems}
return render(request, 'store/cart.html', context)
And this is the other view with the Sendmail() function:
#login_required(login_url='login')
def checkout(request):
if request.method == "POST":
customer = request.user.customer
order, created = Order.objects.get_or_create(customer=customer, complete=False)
items = order.orderitem_set.all()
message_name = request.POST['message-name']
message_email = request.POST['message-email']
message = request.POST['message']
message_to_send = str(message)
# send an email
send_mail(
'message from ' + message_name, # subject
message_to_send, # message
message_email, # from email
['jeampo#outlook.de'], # To Email
)
Thanks for any help!
your question is not fully understood. Do I understand correctly that:
in your for-loop in the cart view you want to save each orderitem of the incompleted customer's order in a MessageItem instance?
for item in items:
item_data = {'customer':customer,
'mItem':item.product.name,
'mQuantity':str(item.quantity),
'mOrderItem': '',} #Not sure what you want with items
message_item = MessageItem(**item_data)
message_item.save()
items is currently a queryset your looping over, and mOrderItem needs a string. So that one doesn't match yet.
I'm not sure if I'm getting the goal of your MessageItem object. Currently each time you call it a new MessageItem is created for each exisiting OrderItem in scope. create_or_update is probably what you want in this situation? Please clarify your goal to better understand the question at hand.
So basically i have to make sure Users that are from the same department field to view and create any datas in the database. Not sure how to apply it using field-based user permissions?
class Profile(AbstractUser):
class Meta:
verbose_name_plural = 'Profiles'
company = models.CharField(max_length=30, null=True)
contact = models.CharField(max_length=20, null=True)
branch = models.ForeignKey('generals.Branch',
on_delete=models.CASCADE)
department = models.ForeignKey('generals.Department',
on_delete=models.CASCADE)
created_by = models.CharField(max_length=20)
modify_by = models.CharField(max_length=20)
modify_date = models.DateTimeField(default=datetime.now, blank=True)
is_active = models.BooleanField(default=False, null=True,
blank=True)
is_superuser = models.BooleanField(default=False, null=True,
blank=True)
is_staff = models.BooleanField(default=False, null=True,
blank=True)
def __str__(self):
return self.username
You should use what's already implemented in Django, and you'll gain a lot of time.
class Person(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
company = models.ForeignKey(Group, on_delete=models.CASCADE)
contact = models.ForeignKey('Person', on_delete=models.CASCADE)
branch = models.ForeignKey('generals.Branch',
on_delete=models.CASCADE)
department = models.ForeignKey('generals.Department',
on_delete=models.CASCADE)
created_by = models.ForeignKey('Person', on_delete=models.CASCADE)
modify_by = models.ForeignKey('Person', on_delete=models.CASCADE)
modify_date = models.DateTimeField(default=datetime.now, blank=True)
even though my eyes are burning because my syntax here is not PEP8 compliant, you should get the big picture: all the permissions are already handled by User and Group.
Just create a Group that has the name of the company, and give this group access (or not) to specific tables.