Home > OS >  How do I write a Django query to get distinct objects linked to another object?
How do I write a Django query to get distinct objects linked to another object?

Time:12-04

I'm using Python 3.9 and Django 3.2. I have this class, which has a field for another ...

class Transaction(models.Model):
    ...

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    account = models.ForeignKey('Account', on_delete=models.CASCADE)

I woudl like to get the distinct set of Account objects, linked to certain transactions., so I treied this

class TransactionManager(models.Manager):
    def get_accounts_with_pending_transactions(self):
        """
        Returns acounts with pending transactions
        """
        return Transaction.objects.filter(status=Transaction.Status.PENDING).values("account").annotate(n=models.Count("pk"))
...

However, the above seems to return a list of dicts as opposed to objects. Thus, I don't have access to all the fields from my Account objects. Is there any way to write a query to get the Account objects such that they are already hydrated as actual objects?

CodePudding user response:

I would use a reverse relation, first edit your model:

class Transaction(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    account = models.ForeignKey('Account', related_name='transactions', on_delete=models.CASCADE)

Then you can write this query:

accounts_with_pending_transactions = Account.objects.filter(transactions__status=Transaction.Status.PENDING).distinct()

I would put that query in a method of the Manager of Account, because the query: "accounts with pending transactions" is naturally tied to accounts and not transactions.

  • Related