0

I want to modify some_date_field value just for filtering purpose. Like using models.Lookup or models.Transform but I dont want to make a raw sql expression.

For instance, using a raw ms sql expression I could write:

WHERE CONVERT(date, FORMAT(some_date_field, '2021MMdd')) >= @some_var

But I how I can do that with Django?

class SomeModel(models.Model):
    some_date_field = models.DateField()

def replace_year(value):
    return value.replace(year=2021) 

SomeModel.objects.filter(
    # replace_year(some_date_field)__gte=some_var
)

Is it possible?

Mikhail
  • 101
  • 2
  • 8

3 Answers3

0

You can use SomeModel.objects.filter({whatever you want to filter}).update(some_date_field={date_value})

if you have any issues see: https://docs.djangoproject.com/en/3.2/ref/models/querysets/#django.db.models.query.QuerySet.update

yo1122
  • 311
  • 4
  • 17
  • Sorry for my inaccuracy. I mean I don't want to update db. I want to customize field's value just for filter. For example in a raw SQL i can do "where dateadd(day, 1, some_date_field) = @some_value" – Mikhail Jul 21 '21 at 17:42
  • If I understood you correctly from comment above you want to ""filter all the records where next day is today". So you're looking for the records which have the date of yesterday. For that you can just use regular filter with datetime and timedelta: from datetime import datetime, timedelta yesterday = datetime.utcnow() - timedelta(days=1) SomeModel.objects.filter(some_date_field__gt=yesterday) will bring you all objects where the next day is today or later. you can switch gt to lt if you want the next day to be today or earlier. – yo1122 Jul 23 '21 at 07:25
  • so as I understand I can't transform left side of condition as I wish? I can use just default simple methods such as __year __gte and etc? – Mikhail Jul 23 '21 at 07:40
  • what if I have `birth_date` field and I want to show "all birth days in next 7 days". So I'd like to transform birth year by current one and then use __range. How I can do it by `filter()`? – Mikhail Jul 23 '21 at 07:48
  • Exactly, filter is a function that expects a QuerySet (django object). You can see all existing methods of building a QuerySet here: https://docs.djangoproject.com/en/3.2/ref/models/querysets/ For your second comment - will have to combine the gt and lt function like so: SomeModel.objects.filter(birth_date__gt=today, birth_date__lt=today+timdelta(days=7)) – yo1122 Jul 25 '21 at 13:04
  • It won't work, because year of `birth_date` is the past. You need to do smth with it before filtering – Mikhail Jul 26 '21 at 06:19
  • It's an equation - it doesn't matter which side you work on. the 3 options you have are: 1. filter on changed value (for example if you want all birthdays the happened at least a year ago you can use "SomeModel.objects.filter(birthday__gt=today - timedelta(days=365))" 2. change the values in the DB (with update as shown in my answer), then filter on them 3. Use F() object like so: "from django.db.models import F SomeObject.objects.filter(birthday__gt=F('birthday')-timedelta(days=375)) the third is closest to what you want - it creates a query and changed the fetched values. – yo1122 Jul 26 '21 at 10:52
0

If you are trying to bulk update all of the objects returned by a queryset and you are using Django 2.2 or greater you can use 'bulk_update'.

See here: Django Bulk Update

If you are dynamically updating values based off of another field check out F expressions they can be used with an 'update' on querysets.

See here: Update dynamically with F expressions

Something to note though, this won't use ModelClass.save method (so if you have some logic inside it won't be triggered).

Take a look at these answers here as well

Zaeem
  • 139
  • 2
  • 4
  • Sorry for my inaccuracy. I mean I don't want to update db. I want to customize field's value just for filter. For example in a raw SQL i can do "where dateadd(day, 1, some_date_field) = @some_value" – Mikhail Jul 21 '21 at 17:44
0

you can use filter() and update() methods in django

Assuming we need to filter some known year which is the old_date variable and the new value contains in the new_date variable

# defing mehod to filter and update new date
def update_date(old_date, new_date):
    SomeModel.objects.filter(some_date_field=old_date).update(some_date_field=new_date)
    return None

you can find some examples using this link.

Hope this will be helpful for you.