Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 533 Vote(s) - 3.6 Average
  • 1
  • 2
  • 3
  • 4
  • 5
django set DateTimeField to database server's current time

#1
How do I do the equivalent of this SQL in django?

UPDATE table SET timestamp=NOW() WHERE ...

Particularly I want to set the datetime field using server's builtin function to get the system time from the server that the database was running on and not the time on the client machine.

I know you can execute the raw sql directly but I'm looking for a more portable solution since databases have different functions for getting the current datetime.

Edit: few people mentioned auto_now param. This updates the datetime on every modification while I want to update datetime only on certain occasions.
Reply

#2
Maybe you should take a look into the documentation:
[Modelfields: DateField][1]

The option 'auto_now' could be just what you are searching for. You can also use it with the DateTimeField. It updates the DateTime each time you're saving the model. So with that option set for your DateTimeField it should be sufficent to retrieve a data-record and save it again to set the time right.


[1]:

[To see links please register here]

Reply

#3
If you want the datetime from a foreign server (i.e., not the one hosting the Django application), you're going to have to peg it manually for a datatime to use. You could use a SQL command like `select now();` or something over SSH, like `ssh user@host "date +%s"`.
Reply

#4
You can use something like this to create a custom value to represent the use of the current time on the database:

class DatabaseDependentValue(object):
def setEngine(self, engine):
self.engine = engine

@staticmethod
def Converter(value, *args, **kwargs):
return str(value)

class DatabaseNow(DatabaseDependentValue):
def __str__(self):
if self.engine == 'django.db.backends.mysql':
return 'NOW()'
elif self.engine == 'django.db.backends.postgresql':
return 'current_timestamp'
else:
raise Exception('Unimplemented for engine ' + self.engine)

django_conversions.update({DatabaseNow: DatabaseDependentValue.Converter})

def databaseDependentPatch(cls):
originalGetDbPrepValue = cls.get_db_prep_value
def patchedGetDbPrepValue(self, value, connection, prepared=False):
if isinstance(value, DatabaseDependentValue):
value.setEngine(connection.settings_dict['ENGINE'])
return value
return originalGetDbPrepValue(self, value, connection, prepared)
cls.get_db_prep_value = patchedGetDbPrepValue

And then to be able to use DatabaseNow on a DateTimeField:

databaseDependentPatch(models.DateTimeField)

Which then in turn finally allows you do a nice and clean:

class Operation(models.Model):
dateTimeCompleted = models.DateTimeField(null=True)
# ...

operation = # Some previous operation
operation.dateTimeCompleted = DatabaseNow()
operation.save()

Reply

#5
Here is how I solved this issue. Hope it saves someone time:

from django.db import models

class DBNow(object):
def __str__(self):
return 'DATABASE NOW()'
def as_sql(self, qn, val):
return 'NOW()', {}
@classmethod
def patch(cls, field):
orig_prep_db = field.get_db_prep_value
orig_prep_lookup = field.get_prep_lookup
orig_db_prep_lookup = field.get_db_prep_lookup

def prep_db_value(self, value, connection, prepared=False):
return value if isinstance(value, cls) else orig_prep_db(self, value, connection, prepared)

def prep_lookup(self, lookup_type, value):
return value if isinstance(value, cls) else orig_prep_lookup(self, lookup_type, value)

def prep_db_lookup(self, lookup_type, value, connection, prepared=True):
return value if isinstance(value, cls) else orig_db_prep_lookup(self, lookup_type, value, connection=connection, prepared=True)

field.get_db_prep_value = prep_db_value
field.get_prep_lookup = prep_lookup
field.get_db_prep_lookup = prep_db_lookup

# DBNow Activator
DBNow.patch(models.DateTimeField)

And then just using the DBNow() as a value where updating and filtering is needed:

books = Book.objects.filter(created_on__gt=DBNow())

or:

book.created_on = DBNow()
book.save()

Reply

#6
My tweaked code works with sqlite, mysql and postgresql and is a bit cleaner than the proposed solutions.

class DBCurrentTimestamp:
def __str__(self):
return 'DATABASE CURRENT_TIMESTAMP()'

def as_sql(self, qn, connection):
return 'CURRENT_TIMESTAMP', {}

@classmethod
def patch(cls, *args):
def create_tweaked_get_db_prep_value(orig_get_db_prep_value):
def get_db_prep_value(self, value, connection, prepared=False):
return value if isinstance(value, cls) else orig_get_db_prep_value(self, value, connection, prepared)

return get_db_prep_value

for field_class in args:
field_class.get_db_prep_value = create_tweaked_get_db_prep_value(field_class.get_db_prep_value)

I activate it @ the end of my models.py file like this:

DBCurrentTimestamp.patch(models.DateField, models.TimeField, models.DateTimeField)

and use it like this:

self.last_pageview = DBCurrentTimestamp()
Reply

#7
I've created a Python Django plugin module which allows you to control the use of `CURRENT_TIMESTAMP` on `DateTimeField` objects, both in specific cases (see `usage` below) as well as automatically for `auto_now` and `auto_now_add` columns.

**django-pg-current-timestamp**

GitHub: [

[To see links please register here]


PyPi: [

[To see links please register here]


Example usage:

from django_pg_current_timestamp import CurrentTimestamp

mm = MyModel.objects.get(id=1)
mm.last_seen_date = CurrentTimestamp()
mm.save()
## Resulting SQL:
## UPDATE "my_model" SET "last_seen_date" = CURRENT_TIMESTAMP;

print MyModel.objects.filter(last_seen_date__lt=CURRENT_TIME).count()

MyModel.objects.filter(id__in=[1, 2, 3]).update(last_seen_date=CURRENT_TIME)
Reply

#8
You can use database function [Now][1] starting Django 1.9:

from django.db.models.functions import Now
Model.objects.filter(...).update(timestamp=Now())


[1]:

[To see links please register here]

Reply

#9
The accepted answer is outdated. Here's the current and most simple way of doing so:

>>> from django.utils import timezone
>>> timezone.now()
datetime.datetime(2018, 12, 3, 14, 57, 11, 703055, tzinfo=<UTC>)
Reply

#10
When creating the table, the field you want to make date now in field after add data add this code to field

class MyModel(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through