3
\$\begingroup\$

What I have

In my application I have a model called cases, which has three fields fulfilled, caducity and prescription; Which are used to keep deadlines for the case. It should be stressed that the three dates may seem at first sight to be the same but they are different terms used in the law. I need to retrieve those cases whose fields fulfilled, caducity and prescription values match a specific date.

class Case(TimeStampedModel, models.Model):
    """Representation of a legal case."""
    fulfillment = models.DateField(
        verbose_name=_("Fulfillment"),
        default=date.today,
        help_text=_("Select the case fulfillment date."),
    )
    caducity = models.DateField(
        verbose_name=_("Caducity"),
        default=date.today,
        help_text=_("Select the case caducity date."),
    )
    prescription = models.DateField(
        verbose_name=_("Prescription"),
        default=date.today,
        help_text=_("Select the case prescription date."),
    )

My solution

Create a custom manager in which I can filter those cases that match a specific date.

from datetime import date, timedelta

TODAY = date.today()
YESTERDAY = TODAY - timedelta(days=1)


class CaseManager(models.Manager):
    """Define a manager for Case model."""
    def all_expired(self) -> "QuerySet[Case]":
        """Get all fulfilled, caducated and prescribed cases."""
        return self.get_queryset().filter(
            Q(fulfillment__range=[YESTERDAY, TODAY])
            | Q(caducity__range=[YESTERDAY, TODAY])
            | Q(prescription__range=[YESTERDAY, TODAY])
        )

class Case(TimeStampedModel, models.Model):
    """Representation of a legal case."""
    # ...fields

    objects = CaseManager()

Then I can retrieve those cases whose expiration date is the same as today or yesterday like this: Case.objects.all_expired()

Problem

This solution may not be scalable, because if the fields that i need to filter go from 3 to 5 or 7 I would have to make the same comparison multiple times:

class CaseManager(models.Manager):
    """Define a manager for Case model."""
    def all_expired(self) -> "QuerySet[Case]":
        """Get all fulfilled, caducated and prescribed cases."""
        return self.get_queryset().filter(
            Q(fulfillment__range=[YESTERDAY, TODAY])
            | Q(caducity__range=[YESTERDAY, TODAY])
            | Q(prescription__range=[YESTERDAY, TODAY])
            | Q(another_field__range=[YESTERDAY, TODAY]) # another field to consider for filtering
            | Q(another_field__range=[YESTERDAY, TODAY]) # another field to consider for filtering
        )

Any suggestion about how to improve this code to make it more maintainable and scalable?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.