QuesrySet eror in django - django

I have some models:
class OrdersTrigger(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
order_trigger = models.ForeignKey(Order, related_name='trigger', on_delete=models.CASCADE)
....
created_at = models.DateTimeField(auto_now_add=True)
class Order(models.Model):
from_bank = models.ForeignKey(Bank, on_delete=models.CASCADE)
to_bank = models.ForeignKey(Bank, related_name='to', on_delete=models.CASCADE)
I'm getting list of orders from this model using filters :
orders = OrdersTrigger.objects.filter(Q(order__from_bank_=baseBank) & Q(order__to_bank=quoteBank))\
.filter(created_at__gte=latest_time).order_by('-created_at')
when i try to iterates through the list:
for order in orders:
or
for order in orders.all():
I'm receiving an error:
The QuerySet value for an exact lookup must be limited to one result
using slicing.
Can you help me with this? I can not understand how to fix this error.

Related

how to use filter in query twice in django

I am trying to filter some data using this query,
get_members = PaymentDetails.objects.filter(participants_name=Participants.objects.filter(participants_name=Profile.objects.get(user=request.user)))
but I am getting this error The QuerySet value for an exact lookup must be limited to one result using slicing. My models looks like this
class Committee(models.Model):
committee_creator = models.ForeignKey(Profile, on_delete=models.CASCADE)
committee_name = models.CharField(max_length=100)
class Participants(models.Model):
participants_name = models.ForeignKey(Profile, on_delete=models.CASCADE)
participants_committee_name = models.ForeignKey(Committee, on_delete=models.CASCADE)
class PaymentDetails(models.Model):
participants_name = models.ForeignKey(Participants, on_delete=models.CASCADE)
participants_paid_status = models.BooleanField(default=False)
participants_amount_paid = models.IntegerField()
try this i will assume that you have OneToOne Relationship between User and Profile.
get_members = PaymentDetails.objects.filter(participants_name__participants_name_id = request.user.profile.pk)

How to copy a object data to another object in Django?

I am trying to create an E-Commerce Website and I am at the Final Step i.e. Placing the Order. So, I am trying to add all the Cart Items into my Shipment model. But I am getting this error.
'QuerySet' object has no attribute 'product'
Here are my models
class Product(models.Model):
productId = models.AutoField(primary_key=True)
productName = models.CharField(max_length=200)
productDescription = models.CharField(max_length=500)
productRealPrice = models.IntegerField()
productDiscountedPrice = models.IntegerField()
productImage = models.ImageField()
productInformation = RichTextField()
productTotalQty = models.IntegerField()
alias = models.CharField(max_length=200)
url = models.CharField(max_length=200, blank=True, null=True)
class Customer(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=100, null=True, blank=True)
email = models.EmailField(max_length=100)
profileImage = models.ImageField(blank=True, null=True, default='profile.png')
phoneNumber = models.CharField(max_length=10, blank=True, null=True)
address = models.CharField(max_length=500, blank=True, null=True)
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
dateOrdered = models.DateTimeField(auto_now_add=True)
orderCompleted = models.BooleanField(default=False)
transactionId = models.AutoField(primary_key=True)
class Cart(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, blank=True, null=True)
dateAdded = models.DateTimeField(auto_now_add=True)
class Shipment(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, blank=True, null=True)
orderId = models.CharField(max_length=100)
products = models.ManyToManyField(Product)
orderDate = models.CharField(max_length=100)
address = models.CharField(max_length=200)
phoneNumber = models.CharField(max_length=13)
I just removed additional functions i.e. __str__ and others.
Here is the views.py
def orderSuccessful(request):
number = Customer.objects.filter(user=request.user).values('phoneNumber')
fullAddress = Customer.objects.filter(user=request.user).values('address')
timeIn = time.time() * 1000 # convert current time in milliSecond
if request.method == 'POST':
order = Shipment.objects.create(customer=request.user.customer, orderId=timeIn,
orderDate=datetime.datetime.now(), address=fullAddress,
phoneNumber=number)
user = Customer.objects.get(user=request.user)
preOrder = Order.objects.filter(customer=user)
orders = Order.objects.get(customer=request.user.customer, orderCompleted=False)
items = orders.cart_set.all() # Here is all the items of cart
for product in items:
product = Product.objects.filter(productId=items.product.productId) # error is on this line
order.products.add(product)
Cart.objects.filter(order=preOrder).delete()
preOrder.delete()
order.save()
else:
return HttpResponse("Problem in Placing the Order")
context = {
'shipment': Shipment.objects.get(customer=request.user.customer)
}
return render(request, "Amazon/order_success.html", context)
How to resolve this error and all the cart items to field products in Shipment model?
Your model is not really consistent at all. Your Cart object is an m:n (or m2m - ManyToMany) relationship between Product and Order. Usually, you would have a 1:n between Cart and Product (a cart contains one or more products). One Cart might be one Order (unless you would allow more than one carts per order). And a shipment is usually a 1:1 for an order. I do not see any of this relationships in your model.
Draw your model down and illustrate the relations between them first - asking yourself, if it should be a 1:1, 1:n or m:n? The latter can be realized with a "through" model which is necessary if you need attributes like quantities.
In this excample, we have one or more customers placing an order filling a cart with several products in different quantities. The order will also need a shipment fee.
By the way: bear in mind that "filter()" returns a list. If you are filtering on user, which is a one to one to a unique User instance, you would better use "get()" as it returns a single instance.
Putting in into a try - except or using get_object_or_404() makes it more stable.
product = Product.objects.filter(productId=items.product.productId)
should be something like:
product = product.product
not to say, it becomes obsolete.
It looks like you make a cart for a product by multiple instances of Cart, the problem is you try to access the wrong variable, also you don't need to filter again when you already have the instance, make the following changes:
carts = orders.cart_set.all() # Renamed items to carts for clarity
for cart in carts:
product = cart.product
order.products.add(product) # The name order is very misleading makes one think it is an instance of Order, actually it is an instance of Shipment
As mentioned above in my comment your variable names are somewhat misleading, please give names that make sense to any variable.

Querying ManyToManyTable In Django

Given the following model, I'm trying to generate a data set that will get the quantity field from OrderItems while also getting the other columns from Item and Order. I'm trying to write the query in Django's ORM but have been having issues.
class Order(models.Model):
items = models.ManyToManyField("Item", through="OrderItems")
order_date = models.DateTimeField()
class Item(models.Model):
name = models.CharField(max_length=250)
orders = models.ManyToManyField("Order", through="OrderItems")
class OrderItems(models.Model):
order = models.ForeignKey("Order", null=False, on_delete=models.CASCADE)
item = models.ForeignKey("Item", null=False, on_delete=models.CASCADE)
quantity = models.IntegerField()
The query I've tried:
Order.objects.prefetch_related('items').filter(id=order_id)
That will get me the Items for the order, but I can't figure out how to get the quantity field.
#William Thank you for your response - if you post it as the answer I'll tick it accordingly. I was missing that those objects are also available in prefetch_related.

Django Models - Reverse Foreign Key

These two classes have Foreign Key to each other and class OrderRow is representing a row which belongs to an Order, I want to know is there any way to set "rows" attribute inside class Order to show a list or query-set of all related order rows by calling it on an object or instance of class Order?
class OrderRow(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
order = models.ForeignKey('Order', on_delete=models.CASCADE)
amount = models.IntegerField(default=0)
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
order_time = models.DateTimeField(auto_now_add=True)
total_price = models.IntegerField(null=True, blank=True)
**rows = models.ForeignKey('OrderRow', on_delete=models.CASCADE, related_name='order_rows')**
You should have ForeignKey in OrderRows with related_name="rows". Like this:
class OrderRow(models.Model):
# rest of the fields
order = models.ForeignKey('Order', on_delete=models.CASCADE, related_name='rows')
Then you can use:
order = Order.objects.first()
for order_row in order.rows.all():
print(order_row)
For more information, please check the documentation.

How to annotate a field from a related model to queryset?

I have two models:
Lot:
class Lot(models.Model):
name = models.CharField(max_length=150, db_index=True, unique=True)
step = models.DecimalField(max_digits=2, decimal_places=2)
and Bid:
class Bid(models.Model):
auction = models.ForeignKey('Lot', on_delete=models.CASCADE)
user_id = models.ForeignKey(User, on_delete=models.CASCADE, to_field='username')
value = models.DecimalField(max_digits=5, decimal_places=2)
Every instance of Lot can have a few Bids, however any instance of Bid is only related to a particular Lot.
I have a working annotation for Lot that gives me the max_bid and next_bid values:
self.auc_set = Lot.objects.annotate(max_bid=Max('bid__value'), next_bid=(Max('bid__value') + F('step')))
And what i can't achieve is getting 3 annotated fields: max_bid, next_bid and last_bidder.
Something like:
self.auc_set = Lot.objects.annotate(max_bid=Max('bid__value'), next_bid=(Max('bid__value') + F('step')), last_bidder=F(bid_set).get('auction_id'= F('id'), 'value'=max_bid)['user_id'])
but working.
Update:
The problem would be solved if i knew how to pass the 'id' from Lot.objects.annotate to the Bid.objects.get part:
auc_set = Lot.objects.annotate(last_bidder=Bid.objects.get(auction_id__exact='need_to_put_something_here', value=Max('value').user_id)