2

I'm new to Django and I'm facing a question to which I didn't an answer to on Stackoverflow. Basically, I have 2 models, Client and Order defined as below:

class Client(models.Model): name = models.CharField(max_length=200) registration_date = models.DateTimeField(default=timezone.now) # .. class Order(models.Model): Client = models.ForeignKey(ModelA, on_delete=models.CASCADE, related_name='orders') is_delivered = models.BooleanField(default=False) order_date = models.DateTimeField(default=timezone.now) # .. 

I would like my QuerySet clients_results to fulfill the 2 following conditions:

  • Client objects fill some conditions (for example, their name start with "d" and they registered in 2019, but it could be more complex)
  • Order objects I can access by using the orders relationship defined in 'related_name' are only the ones that fills other conditions; for example, order is not delivered and was done in the last 6 weeks.

I could do this directly in the template but I feel this is not the correct way to do it. Additionally, I read in the doc that Base Manager from Order shouldn't be used for this purpose. Finally, I found a question relatively close to mine using Q and F, but in the end, I would get the order_id while, ideally, I would like to have the whole object.

Could you please advise me on the best way to address this need?

Thanks a lot for your help!

1 Answer 1

2

You probably should use a Prefetch(..) object [Django-doc] here to fetch the related non-delivered Orders for each Client, and stores these in the Clients, but then in a different attribute, since otherwise this can generate confusion.

You thus can create a queryset like:

from django.db.models import Prefetch from django.utils.timezone import now from datetime import timedelta last_six_weeks = now() - timedelta(days=42) clients_results = Client.objects.filter( name__startswith='d' ).prefetch_related( Prefetch( 'orders', Order.objects.filter(is_delivered=False, order_date__gte=last_six_weeks), to_attr='nondelivered_orders' ) )

This will contain all Clients where the name starts with 'd', and each Client object that arises from this queryset will have an attribute nondelivered_orders that contains a list of Orders that are not delivered, and ordered in the last 42 days.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.