2013-03-09 5 views
1

J'avais dans ma base de données contenant une colonne de dates stockées au format de chaîne (varchar) comme "12-Mar-2011", "11-Apr-2012", etc. Y at-il un moyen de comparer ces dates dans Django? En models.py, la colonne est définie en tant que format de chaîne. par exemple:Comparaison des dates stockées sous forme de chaînes dans Django

startdate = models.CharField(max_length=11) 

Maintenant, je dois comparer ces dates avec une date. Toute aide est appréciée.

Répondre

2

Dans votre models.py, ajoutez une méthode qui retourne un objet datetime, comme ceci:

from datetime import datetime as dt 

class SomeModel(models.Model): 
    # other fields 

    def startdate_as_date(self): 
     return dt.strptime(self.startdate,'%d-%b-%Y') 

J'ai omis une erreur de vérification (comme en vous assurant qu'il est un ensemble startdate) et vérifier si la date est une date valide ou non - vous devriez les ajouter plus tard.

Maintenant, vous pouvez le faire:

foo = SomeModel.objects.get(pk=1) 
the_date = foo.startdate_as_date() 

Maintenant the_date est un objet datetime que vous pouvez utiliser pour faire les comparaisons normales.

+1

Merci pour la réponse rapide. Mais maintenant, puis-je utiliser the_date comme obj = SomeModel.filter (the_date__gte = givenDate)? –

+1

Non, pour ce faire, vous devrez faire une migration de votre base de données et changer le type dans le modèle, comme Francis l'a suggéré. –

+0

Maintenant, existe-t-il un moyen autre que la migration comme solution temporaire pour comparer la date stockée en tant que chaîne dans la base de données? –

0

Ce n'est pas la réponse que vous cherchez, mais ...

Vous vraiment devrait migrer votre base de données à l'aide d'un type models.DateField.

à part cela,

objects = YourModel.objects.raw(""" 
    SELECT 
     STR_TO_DATE(your_string_date_field, '%e-%b-%Y') AS a_mysql_date_field, 
     * 
    FROM your_table 
    """) 

effectue une requête pour obtenir les premières dates de chaîne que les dates de MySQL réels, vous pouvez peut-être l'utiliser pour accomplir tout ce que vous essayez de faire.

+0

Ce que U a suggéré est 100% exact. nous devons faire la migration. Mais maintenant je cherche une solution temporaire pour ce problème. Le problème avec les objets bruts est qu'ils ne peuvent pas être paginés.même nous ne pouvons pas écrire len (obj) pour qu'ils écrivent nos propres fonctions de pagination –

0

Vous pouvez également utiliser des annotations pour créer un nouveau champ virtuel contenant votre valeur dans un format datetime.

from django.db.models.expressions import RawSQL 
Yourmodel.objects.annotate(startdate_datetime = RawSQL("SELECT STR_TO_DATE(startdate, '%%d-%%b-%%Y')",()) 

Notez que:

  • STR_TO_DATE doit être pris en charge par votre base de données. Pour autant que je sache, MySQL et PostgreSQL ont cette fonction.
  • Il y a double % parce que la fonction RawSQL fait réellement une certaine mise en forme en interne, donc % doit être échappée. La valeur du champ sera None si vous demandez n'est pas valide. Par exemple, si vous utilisez des caractères de format non existants ou des valeurs de format non valides. par exemple. si vous essayez de faire correspondre %m avec un mois supérieur à 12 etc.