views:

18

answers:

1
accepted_bids = Bid.objects.filter(shipment__user=u, status='acc').select_related('shipment')
completed_shipments = []
for b in accepted_bids:
    completed_shipments.append(b.shipment)
vehicles_shipped = []
for s in completed_shipments:
    vehicles_shipped.extend(s.items.all())

In the end, I want a list of shipped vehicles. A vehicle is shipped if it's part of a shipment that's completed. A shipment is completed if it has an accepted bid.

I'd prefer not to iterate over the querysets thereby forcing a hit to the DB before its necessary... isn't there a way to get all the associated shipments from a list of bids, for example?


Here's the trimmed down version of my models:

class Shipment(Model):
    user = ForeignKey(User, related_name='shipments')

class ShipmentItem(models.Model):
    shipment = ForeignKey(Shipment, related_name='items')

    class Meta:
    abstract = True

class VehicleItem(ShipmentItem):
    pass

class Bid(Model):
    user = ForeignKey(User, related_name='bids')
    shipment = ForeignKey(Shipment, related_name='bids')
+1  A: 

Supplying the schema is important. But here's a guess:

Vehicle.objects.filter(shipment__bid__status='acc', shipment__user=u)
Ignacio Vazquez-Abrams
Sorry, thought you had enough info. The problem with what you're suggesting is that "bid" is plural (a shipment can have many bids) so I don't think you can filter it like that?
Mark
So you're saying that *all* the bids for a shipment need to be accepted?
Ignacio Vazquez-Abrams
No...not at all. Only one bid can be accepted. But `shipment__bid__status` isn't a thing. It would be `shipment__bids__status`... how would that work? You need to find the vehicles that belong to shipments with an accepted bid... the "many bids" (but only one accepted) thing complicates this.
Mark
Just as written, except you'd need to change the parameter name slightly. Django's ORM mirrors SQL, so just as in SQL joining with bids that are accepted will find *any* shipment that has at least one.
Ignacio Vazquez-Abrams
Hrm... really didn't think that would work. My reasoning was that in most languages something like "user.name" makes sense, but when you have a list of users, "users.name" doesn't make sense. But I guess it's a bit different in this scenario...very cool!
Mark