python - mysqlclient - Django définir DateTimeField à l'heure actuelle du serveur



django mysql windows (6)

Comment puis-je faire l'équivalent de ce SQL dans Django?

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

En particulier, je souhaite définir le champ datetime à l'aide de la fonction intégrée du serveur pour obtenir l'heure système à partir du serveur sur lequel la base de données était en cours d'exécution et non l'heure sur l'ordinateur client.

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

Edit: peu de gens ont mentionné auto_now param. Cela met à jour la date et l'heure à chaque modification alors que je souhaite mettre à jour la date et l'heure uniquement à certaines occasions.


Answer #1

Comme j0ker l'a dit, si vous souhaitez 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 affectation avec python datetime.now() ?

from datetime import datetime

obj.date_modified = datetime.now()

Answer #2

J'ai créé un module plug-in Python Django qui vous permet de contrôler l'utilisation de CURRENT_TIMESTAMP sur des objets 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)

Answer #3

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’active @ la fin de mon fichier models.py comme ceci:

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

et l'utiliser comme ça:

self.last_pageview = DBCurrentTimestamp()

Answer #4

Peut-être devriez-vous jeter un coup d'œil dans la documentation:
Modelfields: DateField

L'option 'auto_now' pourrait correspondre exactement à ce que vous recherchez. Vous pouvez également l'utiliser avec 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 suffire de récupérer un enregistrement de données et de le sauvegarder à nouveau pour régler l'heure correctement.


Answer #5

Voici comment j'ai résolu ce problème. J'espère que ça fait 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 ensuite, en utilisant DBNow () comme valeur pour laquelle la mise à jour et le filtrage sont nécessaires:

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

    or:

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

Answer #6

Vous pouvez utiliser la fonction de base de données. Now partir de Django 1.9:

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




django