Django List Ordering - django

I have a model called bank that has Credit class associated to a user.
Then I have a model called program that has NewProgram class associated also to a user.
Now, I would like to list out all NewProgram objects order by users Credit ascending to my views.py.
And i have no idea how am i going to do that using .order_by method.
I hope someone who could give me some hint.
Heres my code:
Appname: Bank
models.py
class Credit(models.Model):
credit_balance = models.DecimalField(max_digits=6, decimal_places=2)
depositor = models.ForeignKey(User, unique=True)
last_updated = models.DateTimeField(auto_now=True)
def __unicode__(self):
return u'%s' % self.depositor.username
Appname: Programs
class NewProgram(models.Model):
program_creator = models.ForeignKey(User, related_name='program_creator')
joining_credit_value_offer = models.DecimalField(max_digits=6, decimal_places=2)
site = models.ForeignKey('ProgramSite')
uid = models.CharField(max_length=50)
title = models.CharField(max_length=30)
desc = models.CharField(max_length=150)
content = models.TextField(blank=False)
is_published = models.BooleanField(default=True)
referrals = models.ManyToManyField(User, through='ReferredUser')
creation_date = models.DateTimeField(auto_now_add=True)
Heres what i'm trying to accomplish
list = NewProgram.objects.all().order_by(<Users Credit><ASC>)
Thanks a lot, Any help will be much appreciated.

You can try using this
list = NewProgram.objects.all().order_by('-program_creator__credit__credic_balance')
Django follows the relationships through __ .

Hello you can use this:
#Note, no need to use .all()
list = NewProgram.objects.filter(credit_set__depositor="some_user")

Related

Django viewflow running queries in a custom node

I am trying to adapt the Viewflow Dynamicsplit example
The objective is to split approvals of an Order based on OrderLines and to assign them to the appropriate approver. It seems that this should be possible as there seems to be a possibility described in this answer - Assign user to tasks automatically (Viewflow, Django)
The issue is that whenever I try to grab the current order pk in the DynamicSplitActivation - the queryset comes back empty. Not sure where I am going wrong. The queryset works fine if I set the pk manually, but as soon as I try to use a dynamic variable it stops working.
I have listed the flow and models etc. at the end of the post, however, I am guessing the issue is quite basic. Any help would be appreciated!
nodes.py
...
class DynamicSplitActivation(AbstractGateActivation):
def calculate_next(self):
self._order = self.flow_task._order_callback(self.process)
order_id = self._order.pk
# order_id = 28
order_lines = models.OrderLine.objects.filter(order_id=order_id)
project_lines = project_models.ProjectLine.objects.filter(orderline__in=order_lines)
users = User.objects.filter(projectline__in=project_lines).distinct()
self._approvers = users
...
class DynamicSplit(...):
...
def __init__(self, callback):
super(DynamicSplit, self).__init__()
self._order_callback = callback
self._ifnone_next_node = None
...
flows.py
...
approval_split = (
nodes.DynamicSplit(lambda act: act.order)
.IfNone(this.end)
.Next(this.split_approval_budget)
)
models.py
...
class ProjectLine(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
description = models.CharField(max_length=50)
budget_holder = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.SET_NULL, null=True, blank=True)
class Order(models.Model):
description = models.CharField(max_length=30)
class OrderLine(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE)
project_line = models.ForeignKey(project_models.ProjectLine, on_delete=models.SET_NULL, null=True, blank=False)
product = models.ForeignKey(catalogue_models.Product, on_delete=models.CASCADE)
quantity = models.PositiveIntegerField()
budgetholder_approved = models.BooleanField(null=True)
class OrderProccess(Process):
order = models.ForeignKey(Order, blank=True, null=True, on_delete=models.CASCADE)
...

Django Filtering to Get Popular Posts

I have two different models. HitCount model stores IP addresses whose was viewed Post. And what i want is filtering popular 3 posts which viewed more. I've tried some queries but i couldn't. I am sharing my models with you.
class Post(ModelMeta, models.Model):
title = models.CharField(max_length=255, verbose_name='Başlık', unique=True)
slug = models.SlugField(max_length=255, unique=True)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='blog_posts', verbose_name="Yazarı")
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='blog_posts',
verbose_name="Kategorisi", null=True)
tags = models.ManyToManyField(Tag, related_name='blog_posts', verbose_name='Etiketler')
image = models.ImageField(verbose_name='Fotoğraf (800x460)')
content = RichTextField()
description = models.TextField(null=True)
status = models.IntegerField(choices=STATUS, default=0, verbose_name='Yayın Durumu')
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Oluşturulma Tarihi')
updated_at = models.DateTimeField(auto_now=True, verbose_name='Güncellenme Tarihi')
#property
def get_hit_count(self):
return HitCount.objects.filter(post=self).count()
class HitCount(models.Model):
ip_address = models.GenericIPAddressField()
post = models.ForeignKey("Post", on_delete=models.CASCADE)
def __str__(self):
return f'{self.ip_address} => {self.post.title}'
You can try something like this :
most_viewed_posts = Post.objects.all().order_by('-get_hit_count')[3]
I don't think that you can order by 'get_hit_count', but I think those questions can help you : Django order_by a property
Using a Django custom model method property in order_by()
I did what i want with sorted method. Thanks Alexandre Boucard for the resources.
Solution;
sorted(Post.objects.filter(status=1), key=lambda a: a.get_hit_count, reverse=True)
reverse=False as a default and it sorts ascending in this case i want to get reversed so i used reverse=True

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.

Django Joining Tables

I am trying to get the information from one table filtered by information from another table (I believe this is called joining tables).
I have these two models:
class Listing(models.Model):
title = models.CharField(max_length=64)
description = models.CharField(max_length=500)
price = models.DecimalField(max_digits=11, decimal_places=2, validators=[MinValueValidator(Decimal('0.01'))])
category = models.ForeignKey(Category, on_delete=models.CASCADE, default="")
imageURL = models.URLField(blank=True, max_length=500)
creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name="creator", default="")
isOpen = models.BooleanField(default=True)
def __str__(self):
return f"{self.id} | {self.creator} | {self.title} | {self.price}"
class Watchlist(models.Model):
listing = models.ForeignKey(Listing, on_delete=models.CASCADE, related_name="listingWatched", default="")
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="userWatching", default="")
What I need to do is to get all the listings from a specific user Watchlist, the idea is to generate a page with all of the information of each of the listings that are in the user's watchlist. What should I do?
Thanks in advance!
Since is a foreign key, in Django you can access the information by calling the attribute
For example:
my_user = Watchlist.objects.get(pk=1)
print(my_user.listing.title)
You can also access to that attrbute in a query in case you need to filter upwards some value
values = Watchlist.objects.all().filter(listing__title='MyTitle')
my_titles = [x.title for x in values]
print(my_titles)
Or in your case, if you want to list all the title for a specific user
values = Watchlist.objects.all().filter(user='foo_user')
my_titles = [x.listing.title for x in values]
print(my_titles)
More documentation here

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)