ivelum/djangoql

Ability to search for a DateTimeField without entering seconds

Closed this issue · 5 comments

Let's say I have a DateTimeField on the User model called last_sign_in. I want to find all Users who signed in on May 4th 2020.

If I enter last_sign_in = "2020-05-04" then the results just show Users where the last_sign_in was at midnight on the 4th. So as a workaround I need to enter something like last_sign_in >= "2020-05-04" and last_sign_in < "2020-05-05".

It would be nice if there was a shorthand so the workaround wasn't necessary. Thanks!

hey @RobertAKARobin,

you can define a custom search field for that. Consider the following example (assuming that you use it with Django admin):

from djangoql.admin import DjangoQLSearchMixin
from djangoql.schema import DjangoQLSchema, DateField


class UserSignInDateField(DateField):
    model = User
    name = 'last_sign_in_date'

    def get_lookup_name(self):
        return 'last_sign_in__date'


class UserQLSchema(DjangoQLSchema):
    def get_fields(self, model):
        fields = super().get_fields(model)
        if model == User:
            fields += [UserSignInDateField()]
        return fields


@admin.register(User)
class CustomUserAdmin(DjangoQLSearchMixin, admin.ModelAdmin):
    djangoql_schema = UserQLSchema

This code adds a new search field named last_sign_in_date to the User model that performs a comparison by date rather than date and time, exactly as you want. Here is the documentation for custom search fields for a more detailed explanation.

Thanks, @stebunovd ! This is great, but it would be nice if there was an out-of-the-box solution for all DateTime fields, rather than needing to add something in for each separate field.

@stebunovd Oh hey, it looks like this functionality already exists, but isn't documented: https://github.com/ivelum/djangoql/blob/master/djangoql/schema.py#L269

    # Add LIKE operator support for datetime fields. For LIKE comparisons
    # we don't want to convert source value to datetime instance, because
    # it would effectively kill the idea. What we want is expressions like
    #       'created ~ "2017-01-30'
    # to be translated to
    #       'created LIKE %2017-01-30%',
    # but it would work only if we pass a string as a parameter. If we pass
    # a datetime instance, it would add time part in a form of 00:00:00,
    # and resulting comparison would look like
    #       'created LIKE %2017-01-30 00:00:00%'
    # which is not what we want for this case.

I can confirm that last_sign_in ~ "2020-05-04" appears to work just fine.

Lol, good point. I also forgot that it exists. It is safe to use ~ for DateTime, no plans to remove it in any foreseeable future, and yes, it should be documented

hey @RobertAKARobin,

It's implemented in v.0.14.4, hope this helps.

Thanks,
Maxim