django.contrib.auth.models.User.customer.RelatedObjectDoesNotExist: User has no customer - django

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 = []
context = {'items':items}
return render(request,'store/cart.html', context)
That is my add to cart code that still display that there is no related object.

User has no customer means when you are calling customer = request.user.customer, the request user object has no related customer in your database.

Related

How to check the users and if the user is correct then marked the ordered section tick in Django

when I check the Order button then, it should only update the status of the user who has logged in into the system but in my case when x user click the order button then every different user who has not ordered is marked as Ordered which I don't want
def orderList(request):
order_qs = User.objects.get(username=request.user.username)
if request.method == "POST":
status = request.POST.get("order")
if (order_qs):
Order.objects.update(ordered = status)
else:
Order.objects.update(ordered = False)
order = Order.objects.get(user = request.user)
context = {
'order' : order,
}
return render(request, 'user_accounts/order_item.html',context)
It could be that you have to filter your Order objects by your authenticated user before updating. Something like this:
def orderList(request):
order_qs = User.objects.get(username=request.user.username)
if request.method == "POST":
status = request.POST.get("order")
if (order_qs):
Order.objects.filter(customer=request.user).update(ordered = status)
else:
Order.objects.filter(customer=request.user).update(ordered = False)
order = Order.objects.get(user = request.user)
context = {
'order' : order,
}
return render(request, 'user_accounts/order_item.html',context)
Here I am assuming that your Order objects are foreign keyed to your users somehow, with a possible field called customer. Your database may be different.

Auto fill ForeignKey(User) with current signed in user

I have this model called business I want the foreinkey field owner to get the logged in user name automatically without bringing the dropdown button of all users, I have tried some methods, but it doesn't work. How can I autofill the owner field with the logged in user
models.py
class User(AbstractUser):
phone_number = models.CharField(('phone number'), max_length=15,default='+234',
help_text=('Field to save the phone number of the user.'),unique=True)
fullname=models.CharField(max_length=50)
Affidavit=models.ImageField(upload_to='media/')
class Business(models.Model):
owner = models.ForeignKey(User,on_delete=models.CASCADE,default=1)
Phone_Number=models.IntegerField(default='086878432',unique=True)
Figi_ID=models.IntegerField(blank=True)
views.py
def details_business(request):
if request.user.is_authenticated:
business_form=Business()
if request.method=='POST':
business_form=Business_owner_form(request.POST,request.FILES)
if business_form.is_valid():
bform=business_form
bform.owner=request.user
bform.save()
def dashboard(request):
if request.user.is_authenticated:
context = RequestContext(request)
data = Business.objects.all()
current=request.user
print(current)
context={"obj":img}
return render(request,'dashboard.html',context)
You were supposed to call the forms save method.
if business_form.is_valid():
business = business_form.save()
business.owner = request.user
business.save()

Python: How to accept an object (bid) from a list of objects (bids) posted by several users and returns the user details using django

I have created a Django project in which a user can bid with certain amount on a particular item. I have also make a template for the item's owner so that he can see the list of the bidders their amount and rank. In order to accept a bid, i make a Accept field in the list.
Here is my bidder's list page.
When the item owner likes a bid amount, he can accept it and he will be redirect to that particular bidder details.
How can i make a django model, so that the accepted bid will be stored and return the bidder details.
here's my code for bid_create and bid_list:
models.py :
class Bid(models.Model):
user = models.OneToOneField(User, null=True, blank=True)
amount = models.IntegerField()
forms.py:
class BidForm(forms.ModelForm):
class Meta:
model = Bid
fields = ["amount"]
views.py :
#login_required
def bid_create(request):
form = BidForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
print(form.cleaned_data.get("amount"))
instance.user = request.user
instance.save()
context = {
"form": form,
}
return render(request, "bid.html", context)
def bid_list(request):
queryset = Bid.objects.all().order_by('amount')
current_rank = 1
counter = 0
for bid in queryset:
if counter < 1: # for first bid
bid.rank = current_rank
else: # for other bids
if bid.amount == queryset[counter - 1].amount:
# if bid and previous bid have same score,
# give them the same rank
bid.rank = current_rank
else:
# first update the rank
current_rank += 1
# then assign new rank to bid
bid.rank = current_rank
counter += 1
context = {"bid_rank" : "current_rank",
"queryset": queryset,
"title": "List"}
return render(request, 'bid_list.html', context)
This question is very general, so I will just suggest a couple of things.
If you want to store this information I would create a third class (Auction?) which has, at least, an owner. And then in the Bid i would add a ForeignKey to that Auction.
class Auction(models.Model):
owner = ...
accepted_bid = models.ForeignKey(Bid)
Then you need to create a view (accept_bid), and an URl pointing at it, which receives an auction_id and a bid_id. The view will store this accepted bid in the Auction, and redirect to wherever you need.

Django model not being saved after calling save()?

I'm overriding a ModelForm's save method. I'm parsing an Excel file and, if there are some values, I update a quantity in the form's instance related objects. It works the first time, when the instance has no related objects. But the second time, when I'm updating the values, nothing happens. I'm not sure if it has something to do with the commit parameter.
EDIT - Relevant code:
def save(self, commit=True):
"""
Overrides the save method in order to add the product inventory items listed in
the uploaded Excel file, if one was uploaded.
"""
inventory = super(AddOrChangeProductsInventoryForm, self).save(commit)
self._update_inventory_items_quantities()
if not commit:
inventory.save()
self.save_m2m()
return inventory
def _update_inventory_items_quantities(self):
inventory = self.instance
if len(self.excel_data_dict) == 0:
return inventory
non_existing_products = []
for i, product_sku in enumerate(self.excel_data_dict['SKU']):
quantity = self.excel_data_dict['Cantidad'][i]
new_item = inventory.productinventoryitem_set.filter(product__sku=product_sku).first()
if new_item is None:
product = Product.objects.filter(sku=product_sku).first()
if product is None:
# TODO: Raise warning in view
non_existing_products.append(product_sku)
continue
new_item = ProductInventoryItem()
new_item.product = product
new_item.inventory = inventory
new_item.quantity += quantity
# TODO: Check why after first update it's not being updated
If your model has any many-to-many relations, then you need to be sure and use self.save_m2m() in combination with the save method. Here's a quick example:
# save method of your forms.ModelForm class.
def save(self):
obj = super(MyModelForm, self).save(commit=False)
obj.save()
self.save_m2m()
return obj
You are saving form when commit is False.
Replace (line 10):
if not commit:
with:
if commit:
UPDATE:
new_item is new copy of inventory.productinventoryitem_set.filter(product__sku=product_sku).first()
or
ProductInventoryItem()
It is local variable and it is not updating inventory. All these changes will destroy after executing the function. You need to store changes in inventory.
When you are overriding _save_m2m in:
for obj in self.instance.productinventoryitem_set.all():
obj.quantity += 2
obj.save()
Then you are saving changes before destroying.
You can do something like this:
def save(self, commit=True):
inventory = super(AddOrChangeProductsInventoryForm, self).save(commit)
self._update_inventory_items_quantities(inventory, commit)
return inventory
def _update_inventory_items_quantities(self, inventory, commit):
if len(self.excel_data_dict) == 0:
return inventory
non_existing_products = []
for i, product_sku in enumerate(self.excel_data_dict['SKU']):
quantity = self.excel_data_dict['Cantidad'][i]
new_item = inventory.productinventoryitem_set.filter(product__sku=product_sku).first()
if new_item is None:
product = Product.objects.filter(sku=product_sku).first()
if product is None:
# TODO: Raise warning in view
non_existing_products.append(product_sku)
continue
new_item = ProductInventoryItem()
new_item.product = product
new_item.inventory = inventory
new_item.quantity += quantity
if commit:
new_item.save()

Can i have help on how i can save a foreignkey in a model?

I have two models Order and OrderItem.
The process to make an order starts with the OrderItem model.
class OrderItem(SmartModel):
shopping_id = models.CharField(max_length=50,db_index=True)
quantity = models.IntegerField(default=0)
item = models.ForeignKey(Item)
order = models.ForeignKey(Order,null=True,blank=True)
OrderItem represents an item and is a modelform with one field being quantity others are excluded
i validate the form and create the item like so,
def show_item(request,id):
# need to evaluate the HTTP method
if request.method == 'POST':
a = Item.objects.get(pk=id)
form = PartialOrderItemForm(request.POST,instance=a)
# check validation of posted data
if form.is_valid():
order.add_to_order(request,a)
# if test cookie worked, get rid of it
if request.session.test_cookie_worked():
request.session.delete_test_cookie()
url =urlresolvers.reverse('order_index')
# redirect to order page
return HttpResponseRedirect(url)
else:
form = PartialOrderItemForm()
request.session.set_test_cookie()
context={
'form':form,
}
return render_to_response('item.html',context,context_instance=RequestContext(request))
the function called after is_valid i.e order.add_to_order creates and saves an item.
def add_to_order(request,obj):
postdata = request.POST.copy()
#get quantity added, return 0 if empty
quantity = postdata.get('quantity',0)
# fetch the item or return missing page error_message
i = get_object_or_404(Item,pk=obj.id)
# get items in order
order_items = get_order_items(request)
item_in_orders = False
# check to see if item is already in order
for order_item in order_items:
if order_item.item.id == i.id:
#update the quantity if found
order_item.augment_quantity(quantity)
item_in_orders = True
if not item_in_orders:
# creat and save a new order item
anon_user = User.objects.get(id=settings.ANONYMOUS_USER_ID)
oi=OrderItem.objects.create(shopping_id=_shopping_id(request),
quantity=quantity,
item=i,
created_by=anon_user,
modified_by=anon_user)
oi.save()
when a customer is done creating an item(in the database), they fill in a form which is Order
class Order(SmartModel):
#each individual status
SUBMITTED = 1 # the credit card was valid or mobilemoney was recieved.It is ready for us to process the order
PROCESSED = 2 # After submitted orders are reviewed, we can mark them as processed, letting deliverers know order is ready to be shipped
DELIVERED = 3 # the order has been processed and approved by the adminstrator(in this case us), it is delivered.
PICKED_UP =4 # the order has been processed and is picked up by customer
CANCELLED = 5 # Customer called the company and decided they didnt want to go through with the order either by phone or email.
# SET OF POSSIBLE STATUSES
ORDER_STATUSES = ((SUBMITTED,'Submitted'),(PROCESSED,'Processed'),(DELIVERED,'Delivered'),(PICKED_UP,'picked_up'),(CANCELLED,'Cancelled'),)
#Order info
date = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=ORDER_STATUSES, default=SUBMITTED)
# customer = models.ForeignKey(Customer,null=True,blank=True,help_text="The customer who made this order",default=None,)
restaurant = models.ForeignKey(Restaurant,null=True,blank=True,default = None,help_text="The restaurant the customer order from")
#contact info
email = models.EmailField(max_length=50,help_text="Needed as alternative")
mobile = PhoneNumberField(max_length=20,default='+25078######',help_text="Needed to communicate and confirm payment from mobile money")
#billing information
billing_name= models.CharField(max_length=50,help_text="Needed so we can deliver to the right individual")
billing_address= models.CharField(max_length=50,help_text="Needed for delivery purposes, should be office address.")
billing_city = models.CharField(max_length=50,help_text="F4L services are only in selected cities.")
Order is a modelform that i validate and save like so.
def show_checkout(request):
if order.is_empty(request):
cart_url = urlresolvers.reverse('order_index')
return HttpResponseRedirect(cart_url)
if request.method == 'POST':
postdata = request.POST.copy()
form = forms.CheckoutForm(request.POST,postdata)
if form.is_valid():
anon_user = User.objects.get(id=settings.ANONYMOUS_USER_ID)
obj = form.save(commit=False)
obj.created_by = anon_user
obj.modified_by = anon_user
obj.save()
if postdata['submit'] == 'place order':
reciept_url = urlresolvers.reverse('checkout_reciept')
return HttpResponseRedirect(reciept_url)
else:
form = forms.CheckoutForm
context = {
'form':form,
}
return render_to_response('checkout/checkout.html',context,context_instance=RequestContext(request))
i should point out that OrderItem is called before Order..much of where the confusion is coming from
to return all OrderItem objects related to Order i do as suggested by the django documentation https://docs.djangoproject.com/en/dev/topics/db/queries/#following-relationships-backward
>>> from orders.models import OrderItem,Order
>>> a = Order.objects.get(id=1)
>>> a
<Order: blah blah blahbaah#blahblah.com +250780000000 1 2013-02-26 17:25:23.138738+00:00>
>>> a.orderitem_set.all()
[]
I am thinking its empty because i didnt save the foreignkey, but i am really confused about how to go about that. Any help is appreciated..
You just need to pass in (or somehow obtain) the object for the order.
Assuming the PK of the order is in your POST vars, you could do this:
def add_to_order(request,obj):
postdata = request.POST.copy()
order = Order.objects.get(pk=postdata.get('order_id'))
…
oi=OrderItem.objects.create(order=order, shopping_id=_shopping_id(request), …)
Based on your comment below though, you're creating your order AFTER you create the orderitem, making the code above pointless.
If the order hasn't been created yet, there's absolutely no way for you to tie the order item to the order. At least not without doing something else.
Here's what I'd do.
Add a new field to your OrderItem:
order_uuid = models.CharField(max_length=25, blank=False, null=True)
When you start your order process (wherever you start it), create a UUID using python's uuid package:
import uuid
temporary_order_uuid = uuid.uuid4()
Pass this value through each of your order steps, final saving it to the orderitem when you create it.
oi=OrderItem.objects.create(order_uuid=temporary_order_uuid, …)
After you create your order, go back and update all orderitems that contain that uuid with the order's pk:
order_items = OrderItems.objects.get(order_uuid=temporary_order_uuid)
for oi in order_items:
oi.order = order
oi.save()
A much cleaner solution would be to create your orderitems AFTER you create the order in the database, but I don't know all the various requirements of your app.