4

我正在为代表账单的对象制作一个 crud 接口,如水费单、电费单等。

我正在使用 sqlalchemy 来处理数据,使用 wtforms 来处理表单,并使用烧瓶来服务它。

这是我的路线的样子,用于编辑现有账单的表格:

@app.route('/edit_bill/<int:bill_id>', methods = ['GET'])
def edit_bill(bill_id):
    s = Session()
    bill = s.query(Bill).filter_by(id=bill_id).first()
    form = BillForm(obj=Bill)
    return render_template('edit_bill.html', form = form)

使用 wtforms,我将 bill 对象传递给 BillForm 构造函数,确保将表示要编辑的账单的数据填充到表单中。

这就是它窒息的地方。这是一个例外:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Bill.date_due has an attribute 'strftime'

现在,我进入了 python shell 并查询了一个账单,以确保 date_due 上面有一个datetime.date对象,确实如此。我使用 Jinja 来构建我的前端,所以我已经研究过创建一个模板过滤器,但我不知道这将如何与 wtforms 一起工作,而且看起来 sqlalchemy 无论如何都是令人窒息的。

那么它是做什么的呢?我非常有信心我只需要弄清楚如何将该datetime.date对象变成一个字符串,但我不确定如何去做。

哈尔普。谢谢!

编辑:这是 BillForm 类:

class BillForm(Form):
    id                  = HiddenField()
    name                = TextField(u'Name:', [validators.required()])
    pay_to              = TextField(u'Pay To:',[validators.required()])
    date_due            = DateField(u'Date Due:',[validators.required()])
    amount_due          = IntegerField(u'Amount Due:', [validators.required()])
    date_late           = DateField(u'Late After:',[validators.required()])
    amount_late         = IntegerField(u'Late Amount:', [validators.required()])
    date_termination    = DateField(u'Termination Date:',[validators.required()])

还有映射类:

class Bill(Base):
    __tablename__ = 'bills'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    pay_to = Column(String)
    amount_due = Column(Integer)
    date_due = Column(Date)
    amount_late = Column(Integer)
    date_late = Column(Date)
    date_termination = Column(Date)

    def __init__(self, name, pay_to, amount_due, date_due, amount_late, date_late, date_termination):
        self.name               = name
        self.pay_to             = pay_to
        self.amount_due         = amount_due
        self.date_due           = date_due
        self.amount_late        = amount_late
        self.date_late          = date_late
        self.date_termination   = date_termination

    def __repr__(self):
        return "<Bill ('%s', '%s', '%s', '%s')>" % (self.name, self.pay_to, self.amount_due, self.date_due)
4

1 回答 1

5

啊,我花了一些时间才弄清楚你哪里出错了,但我想我发现了。这是你的代码:

@app.route('/edit_bill/<int:bill_id>', methods = ['GET'])
def edit_bill(bill_id):
    s = Session()
    bill = s.query(Bill).filter_by(id=bill_id).first()
    form = BillForm(obj=Bill)
    return render_template('edit_bill.html', form = form)

现在,如果将一个类作为objBillForm 中的 kwarg 传递,表单就会被各种奇怪的对象填充。例如,如果我复制你所做的并进行检查form.date_due.data,它会说它是一个<sqlalchemy.orm.attributes.InstrumentedAttribute at 0x277b2d0>对象。与错误消息中的说明一样,此对象没有strftime属性。

因此,您的错误出现在您提供的代码的第 5 行。如果您想使用您在第 4 行中检索到的账单对象的详细信息填充表单,请将第 5 行替换为form = BillForm(obj=bill)。如您所见,“细微”的区别在于 bill 中的小写 b。我复制了您的代码,并确信应该解决问题。

如果您有兴趣,这就是我通常制作编辑视图的方式。

@app.route('/edit_bill/<int:bill_id>', methods = ['GET', 'POST'])
def edit_bill(bill_id):
    s = Session()
    bill = s.query(Bill).filter_by(id=bill_id).first()
    form = BillForm(request.form, obj=bill)
    if request.method == 'POST' and form.validate():
        form.populate_obj(bill)
        s.add(bill)
        s.commit()
        # Do some other stuff, for example set a flash()
    return render_template('edit_bill.html', form = form)

我有一段时间没有使用 SQLAlchemy,所以我可能在那里犯了几个错误。希望这可以帮助!如果这回答了您的问题,请“接受”答案。

于 2013-05-23T17:30:26.147 回答