pythondjangodjango-commands

How to filter using an expression in Django


I'd like to filter that implements this "pseudocode":

   Post.objects.filter(Post.timestamp + Post.duration > datetime.datetime.now())

I also would like to wrap this in a Django management command.

Any help would be great!


Solution

  • Filter

    Not sure how your fields look but here's a hint:

    Let's compose an F expression like this F('timestamp') - F('duration'), and annotate our query with it:

    from django.db.models import DateTimeField, ExpressionWrapper, F
    
    Post.objects.annotate(
            timestamp_minus_duration=ExpressionWrapper(
                F('timestamp') + F('duration'),
                output_field=DateTimeField()
            )
        )
    

    Now you can filter with that annotated field

       Post.objects.annotate(
            timestamp_minus_duration=ExpressionWrapper(
                F('timestamp') + F('duration'),
                output_field=DateTimeField()
            )
        ).filter(
            timestamp_minus_duration__gt=datetime.datetime.now()
        )
    

    ref: https://docs.djangoproject.com/en/1.9/topics/db/queries/#using-f-expressions-in-filters

    ref: https://docs.djangoproject.com/es/1.9/ref/models/expressions/#using-f-with-annotations

    ref: https://docs.djangoproject.com/es/1.9/topics/db/aggregation/#filtering-on-annotations

    Management Command

    Just put the code in the handle() method of the command

    # yourapp/management/commands/deletepost.py
    
    from django.core.management.base import BaseCommand, CommandError
    from yourapp.models import Post
    
    class Command(BaseCommand):
        help = 'Describe your cmd here'
    
        def handle(self, *args, **options):
               Post.objects.annotate(...).filter(...).delete()
    

    More details: https://docs.djangoproject.com/en/1.9/howto/custom-management-commands/