0

検証にはpythonのcolanderライブラリを使用しています。私のコードには、colander.DateTime() タイプの createdon フィールドがあります。datetime.datetime.now() の値を指定すると、createdon フィールドの日付が無効であるという例外が発生して失敗します。何が問題なのですか?

pythonモジュールのコードは次のとおりです。

import colander
import htmllaundry
import pymongo
import random
import datetime
import hashlib
from pymongo import Connection

# Database Connection
HOST = "localhost"
PORT = 27017
DATABASE = "testdb"
conn = Connection(HOST, PORT)
db = conn[DATABASE]

# function to generate random string
def getRandomString(wordLen):
    word = ''
    for i in range(wordLen):
        word += random.choice('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789')
    return word

# Colander classe for User object
class User(colander.MappingSchema):
    username = colander.SchemaNode(colander.String(),validator=colander.Length(3,100))
    email = colander.SchemaNode(colander.String(),validator=colander.All(colander.Email(),colander.Length(3,254)))
    password = colander.SchemaNode(colander.String(),validator=colander.Length(8,100))
    isactive = colander.SchemaNode(colander.Boolean())
    code = colander.SchemaNode(colander.String(),validator=colander.Length(64,64))
    name = colander.SchemaNode(colander.String(),validator=colander.Length(3,100)) 
    picture = colander.SchemaNode(colander.String())
    about = colander.SchemaNode(colander.String(),preparer=htmllaundry.sanitize,validator=colander.Length(0,1024))
    ipaddress = colander.SchemaNode(colander.String())
    createdon = colander.SchemaNode(colander.DateTime())
    updatedon = colander.SchemaNode(colander.DateTime())
    status = colander.SchemaNode(colander.Int(),validator=colander.Range(0,4)) #0->active, 1->Deleted, 2->Suspended, 3->Deactivated

# getUser(username)
def getUser(username):
    user = db.users.find_one({"username" : username })
    return user

# getUserByEmail(email)
def getUserByEmail(email):
    user = db.users.find_one({"email" : email })
    return user


# createUser(userdata) #accepts a dictionary argument
def createUser(userdata):
    schema = User() # generate schema object for User Validation Class
    try:
        # set current date/time in createdon/updatedon

        userdata['createdon'] = datetime.datetime.now()
        userdata['updatedon'] = userdata['createdon']

        # generate unique activation code, set isactive to False, and set status to 0
        randomCode = getRandomString(64)
        userdata['code'] = hashlib.sha256(randomCode).hexdigest()
        userdata['isactive'] = False
        userdata['status'] = 0

        # validate and deserialize userdata 
        schema.deserialize(userdata)

        # sha256 the password
        userdata['password'] = hashlib.sha256(userdata['password']).hexdigest()

        # save the userdata object in mongodb database
        result = db.users.insert(userdata)

        # return the result of database operation and final userdata object
        return result, userdata
    except colander.Invalid, e:
        errors = e.asdict()
        return errors, userdata

test.py での使用方法は次のとおりです。

import usermodule

UserObject = {
    'username':'anuj',
    'email': 'anuj.kumar@gmail.com',
    'password':'testpassword',
    'name':'Anuj Kumar',
    'picture':'/data/img/1.jpg',
    'about':'Hacker & Designer, New Delhi',
    'ipaddress':'127.0.0.1'
    }

result, data = usermodule.createUser(UserObject)

print result
print data

次のエラーが表示されます:

anuj@anuj-Vostro-1450:~/Projects/test$ python test.py
{'createdon': u'Invalid date', 'updatedon': u'Invalid date'}
{'username': 'anuj', 'picture': '/data/img/1.jpg', 'about': 'Hacker & Designer, New Delhi', 'code': 'd6450b49e760f96256886cb24c2d54e8e8033293c479ef3976e6cbeabbd9d1f1', 'name': 'Anuj Kumar', 'updatedon': datetime.datetime(2012, 9, 14, 16, 16, 32, 311705), 'createdon': datetime.datetime(2012, 9, 14, 16, 16, 32, 311705), 'status': 0, 'password': 'testpassword', 'ipaddress': '127.0.0.1', 'email': 'anuj.kumar@gmail.com', 'isactive': False}
4

1 に答える 1

2

cstructを逆シリアルdatetime.datetime化しており、インスタンスが含まれています。Colander は、、、 などの単純な型のみを想定しています。intfloatstr

datetime 値を ISO 形式の文字列にすると、問題なく動作します。

>>> import datetime
>>> import colander
>>> colander.SchemaNode(colander.DateTime()).deserialize(datetime.datetime.now())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/private/tmp/colander/lib/python2.7/site-packages/colander/__init__.py", line 1598, in deserialize
    appstruct = self.typ.deserialize(self, cstruct)
  File "/private/tmp/colander/lib/python2.7/site-packages/colander/__init__.py", line 1265, in deserialize
    mapping={'val':cstruct, 'err':e}))
colander.Invalid: {'': u'Invalid date'}
>>> colander.SchemaNode(colander.DateTime()).deserialize(datetime.datetime.now().isoformat())
datetime.datetime(2012, 9, 14, 13, 5, 37, 666630, tzinfo=<colander.iso8601.Utc object at 0x109732d50>)

datetime.datetime.now()にはタイムゾーン情報が含まれておらず、保持されないことに注意してください.isoformat()。一方、Colander は ISO 8601 文字列を UTC タイムゾーンのタイムスタンプとして解析するため、代わりにクラス メソッドを使用して同じタイムゾーンでタイムスタンプを生成する必要があります。datetime.datetime.utcnow()

>>> colander.SchemaNode(colander.DateTime()).deserialize(datetime.datetime.utcnow().isoformat())
datetime.datetime(2012, 9, 14, 11, 23, 25, 695256, tzinfo=<colander.iso8601.Utc object at 0x1005aaf10>)

だから、交換

    userdata['createdon'] = datetime.datetime.now()

    userdata['createdon'] = datetime.datetime.utcnow().isoformat()

colander は、正しいタイムゾーンを使用して喜んでそれを解析します。

于 2012-09-14T11:09:04.427 に答える