django définir DateTimeField à l’heure actuelle du serveur

Comment faire l’équivalent de ce SQL dans Django?

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

En particulier, je veux définir le champ datetime en utilisant la fonction intégrée du serveur pour obtenir l’heure système du serveur sur lequel la firebase database était exécutée et non l’heure sur l’ordinateur client.

Je sais que vous pouvez exécuter directement le fichier sql brut, mais je recherche une solution plus portable car les bases de données ont des fonctions différentes pour obtenir l’heure actuelle.

Edit: peu de personnes ont mentionné auto_now param. Cela met à jour le datetime à chaque modification, alors que je veux mettre à jour le datetime uniquement à certaines occasions.

Comme j0ker l’a dit, si vous voulez une mise à jour automatique de l’horodatage, utilisez l’option auto_now . Par exemple date_modified = models.DateTimeField(auto_now=True) .

Ou si vous voulez le faire manuellement, n’est-ce pas une simple atsortingbution avec python datetime.now() ?

 from datetime import datetime obj.date_modified = datetime.now() 

La réponse acceptée est obsolète. Voici la manière la plus simple et actuelle de le faire:

 from django.utils import timezone timezone.now() 

Voici comment j’ai résolu ce problème. J’espère que ça fera gagner du temps à quelqu’un:

 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) 

Et puis, il suffit d’utiliser DBNow () comme valeur lorsque la mise à jour et le filtrage sont nécessaires:

 books = Book.objects.filter(created_on__gt=DBNow()) or: book.created_on = DBNow() book.save() 

Vous pouvez utiliser quelque chose comme ceci pour créer une valeur personnalisée pour représenter l’utilisation de l’heure actuelle dans la firebase 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 

Et puis pour pouvoir utiliser DatabaseNow sur un DateTimeField:

 databaseDependentPatch(models.DateTimeField) 

Ce qui permet alors à son tour de faire une belle et propre:

 class Operation(models.Model): dateTimeCompleted = models.DateTimeField(null=True) # ... operation = # Some previous operation operation.dateTimeCompleted = DatabaseNow() operation.save() 

Mon code modifié fonctionne avec sqlite, mysql et postgresql et est un peu plus propre que les solutions proposées.

 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) 

Je l’activer @ la fin de mon fichier models.py comme ceci:

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

et l’utiliser comme ceci:

 self.last_pageview = DBCurrentTimestamp() 

J’ai créé un module de plug-in Python Django qui vous permet de contrôler l’utilisation de CURRENT_TIMESTAMP sur les objects DateTimeField , à la fois dans des cas spécifiques (voir usage ci-dessous) et automatiquement pour les colonnes auto_now et auto_now_add .

django-pg-current-timestamp

GitHub: https://github.com/jaytaylor/django-pg-current-timestamp

PyPi: https://pypi.python.org/pypi/django-pg-current-timestamp

Exemple d’utilisation:

 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) 

Si vous voulez le datetime d’un serveur étranger (c.-à-d. Pas celui hébergeant l’application Django), vous devrez le connecter manuellement pour pouvoir utiliser un datatime. Vous pouvez utiliser une commande SQL comme select now(); ou quelque chose sur SSH, comme ssh user@host "date +%s" .

Peut-être devriez-vous jeter un coup d’oeil dans la documentation:
Modelfields: DateField

L’option ‘auto_now’ peut être juste ce que vous recherchez. Vous pouvez également l’utiliser avec le DateTimeField. Il met à jour le DateTime chaque fois que vous enregistrez le modèle. Donc, avec cette option définie pour votre DateTimeField, il devrait être suffisant de récupérer un enregistrement de données et de le sauvegarder à nouveau pour définir l’heure correcte.

Vous pouvez utiliser la fonction de firebase database Maintenant en commençant Django 1.9:

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