to get a solution to my problem but still frusterated.
The problem is about having three tables that have a relation sequentialy between each other. More specifically table Person has a reverse relation with table PersonSession and the second one has a reverse relation with Billing table. And the problem arises when we want to filter some persons based on their sessions and their billings.
20)
last_name = models.CharField(max_length=20)
class PersonSession(models.Model):
start_time = models.DateTimeField(auto_now_add=True)
end_time = models.DateTimeField(null=True,
blank=True)
person = models.ForeignKey(Person, related_name='sessions')
class Billing(models.Model):
DEBT = 'DE'
BALANCED = 'BA'
CREDIT = 'CR'
session = models.OneToOneField(PersonSession,
blank=False,
null=False,
related_name='billing')
STATUS = ((BALANCED, 'Balanced'),
(DEBT, 'Debt'),
(CREDIT, 'Credit'))
status = models.CharField(max_length=2,
choices=STATUS,
blank=False,
default=BALANCED
)
#views.py
class PersonFilter(django_filters.FilterSet):
start_time = django_filters.DateFromToRangeFilter(name='sessions__start_time',
distinct=True)
billing_status = django_filters.ChoiceFilter(name='sessions__billing__status',
choices=Billing.STATUS,
distinct=True)
class Meta:
model = Person
fields = ('first_name', 'last_name')
class PersonList(generics.ListCreateAPIView):
queryset = Person.objects.all()
serializer_class = PersonSerializer
filter_backends = (django_filters.rest_framework.DjangoFilterBackend)
filter_class = PersonFilter
There is a difference between when we call a simple filter like this:
Person.objects.filter(Q(sessions__start_time__gte='2000-02-01') & \
Q(sessions__start_time__lte='2000-03-01') & \
Q(sessions__billing__status=Billing.DEBT))
or something like this:
Person.objects.filter(Q(sessions__start_time__gte='2000-02-01') & \
Q(sessions__start_time__lte='2000-03-01')).filter(
Q(sessions__billing__status=Billing.DEBT))
As the answer to my question stated the second one creates two inner join on a same table PersonSession that is obviously wrong, but when using djnago-filter, filters on qeryset would be applied sequentially and the result is like the second query which is incorrect.
I hope to find a way to keep my filters working and able to use them together or each of them separately.