0

The following returns 3 objects but this should be only 1. Since there is only 1 InsiderTrading object that has these filters, but there are 3 owners.

quarter_trading_2018q1 = InsiderTrading.objects.filter(
    issuer=company_issuer.pk,
    owners__company=company.pk,
    transaction_date__range=["2018-01-01", "2018-03-30"]
).prefetch_related('owners')

enter image description here

If I however remove the owner_company filter it return 1 (correct behaviour)

quarter_trading_2018q1 = InsiderTrading.objects.filter(
    issuer=company_issuer.pk,
    transaction_date__range=["2018-01-01", "2018-03-30"]
).prefetch_related('owners')

enter image description here

But I still want to filter on owners_company, how do I get 1 returned then?

Sharpless512
  • 3,062
  • 5
  • 35
  • 60

2 Answers2

1

You should add a distinct().

InsiderTrading.objects.filter(
    issuer=company_issuer.pk,
    owners__company=company.pk,
    transaction_date__range=["2018-01-01", "2018-03-30"]
).distinct().prefetch_related('owners')
Sharpless512
  • 3,062
  • 5
  • 35
  • 60
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
0

If distinct works: this means that this query results with

InsiderTrading.objects.filter(
    issuer=company_issuer.pk,
    owners__company=company.pk,
    transaction_date__range=["2018-01-01", "2018-03-30"]
)

with multiple results not one.

Django docs states

select_related() "follows" foreign-key relationships, selecting additional related-object data when it executes its query.

prefetch_related() does a separate lookup for each relationship, and does the "joining" in Python.

I'd say use select_related instead. check https://stackoverflow.com/a/31237071/4117381

Another solution is to use group_by owner_id.

Ahmed Hosny
  • 1,162
  • 10
  • 21