Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django: Filter by calculated field

In my Django project I need to calculate a date range for a trip to see if the trip is currently on its way.

class TourTemplate(models.Model):
    length = models.IntegerField()
    description = models.TextField(max_length=1000)
...

class Trip(models.Model):
    tourtemplate = models.ForeignKey(TourTemplate)
    start = models.DateField()
...

I added this to my Trip model:

def end(self):
    length = self.tourtemplate.length
    start = self.start
    a = start + timedelta(days=length)
    return a

In the shell it works and returns the end date for single objects. But how can I filter my queryset so that I only get objects between start and the calculated end date?

like image 325
yabd Avatar asked Mar 18 '26 01:03

yabd


1 Answers

# First, define a manager subclass
class TripManager(models.Manager):
    def get_queryset(self):
        length= self.tourtemplate.length
        start= self.start
        end=start+ timedelta(days=length)
        return super(TripManager, self).get_queryset().filter(date__range=[start, end])

class Trip(models.Model):

    objects = models.Manager() # The default manager.
    current_trip = TripManager() # New manager

Now, you can call:

Trip.current_trip.all()

Two take aways from this:

  1. Functions that you have defined inside your model, is callable only on the instance of that model (where the function resides).
  2. And because of point 1, custom model manager is required in your case. Read about them from this link. Your default manager is called by Model.objects.all() and if you want to change or modify the queryset that your defualt manager returns, defining a custom manager comes handy.

Try the above solution. Hope it helps :)

like image 137
Shubhanshu Avatar answered Mar 19 '26 13:03

Shubhanshu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!