Reputation: 33
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:
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!
Upvotes: 2
Views: 418
Reputation: 476584
You probably should use a Prefetch(..)
object [Django-doc] here to fetch the related non-delivered Order
s for each Client
, and stores these in the Client
s, 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 Client
s 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 Order
s that are not delivered, and ordered in the last 42 days.
Upvotes: 2