xpanta
xpanta

Reputation: 8418

django: correctly retrieve data where date and time are greater than now

I have a model which describes an event like this:

class Event(models.Model):
    date = models.DateField()
    time = models.TimeField()

I would like to retrieve all future events (ie date greater than now.date()). However If date is today, I would like to retrieve today's events with time greater than now.time().

This is what I am doing:

events = Event.objects.filter(date__gte=now.date()).filter(time__gte=now.time()).order_by('-date')

where now = datetime.datetime.now()

But this is wrong, because it gives me an empty set if the only event is tomorrow and its time is less than current time (for example if event is tomorrow at 09:00 and today is 19:00)

is this possible in django?

PS: I would like to avoid iterating through the set.

Upvotes: 18

Views: 35279

Answers (2)

Anshab Tp
Anshab Tp

Reputation: 56

What i did when i had a similar problem: My Problem is to find Upcoming events and Past events from my event section and i sloved like this... <---#Problemsolving #Datefiltering #Django #Backend --->

@api_view(["GET"])
@check_mode## Heading ##
def past_events(request):
    profile_data = get_current_profile(request)
    profile_id = profile_data["user_profile_data"]["user_profile_pk"]
    today = date.today()

    if Event.objects.filter(event_user=profile_id,end_date__lt=today).exists():
        instances = Event.objects.filter(event_user=profile_id,end_date__lt=today)

        serialized_data = EventSerializer(
            instances, 
            context = {
                "request": request
            },
            many = True
        ).data

        response_data = {
            "Statuscode":6000,
            "data" : serialized_data,
            "title": "Past event"
            }
    else:
        response_data = {
            "StatusCode" :6001,
            "title" : "Failed",
            "message" : "Events not found" 
        }
    return Response(response_data, status=status.HTTP_200_OK)

@api_view(["GET"])
@check_mode
def upcoming_events(request):
    profile_data = get_current_profile(request)
    profile_id = profile_data["user_profile_data"]["user_profile_pk"]
    today = date.today()

    

    if Event.objects.filter(event_user=profile_id,start_date__gt=today).exists():
        instances = Event.objects.filter(event_user=profile_id,start_date__gt=today)

        serialized_data = EventSerializer(
            instances, 
            context = {
                "request": request
            },
            many = True
        ).data

        response_data = {
            "Statuscode":6000,
            "data" : serialized_data,
            "title": "Upcoming event"
            }
    else:
        response_data = {
            "StatusCode" :6001,
            "title" : "Failed",
            "message" : "Events not found" 
        }
    return Response(response_data, status=status.HTTP_200_OK)

Upvotes: 2

Alasdair
Alasdair

Reputation: 308889

Use Q objects, which allow you to make queries with OR statements.

from django.db.models import Q
Events = Event.objects.filter(
    Q(date=now.date(),
    time__gte=now.time()
    |Q(date__gt=now.date())
).order_by('-date')

Note that you might want to sort on the time field as well:

order_by('-date', '-time')

Upvotes: 29

Related Questions