Fill out a WTForms form object with datetime.date

I am preparing a rough interface for the object representing the bill, as in the water bill, electricity bill, etc.

I use sqlalchemy for data processing, wtforms for processing forms and a jar for serving it.

Here, what my route looks like, is a form for editing an existing account:

@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) 

Using wtforms, I pass the bill object to the BillForm constructor, ensuring that the data representing the bill is changed, filled out on the form.

Here he suffocates. Here's the exception:

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

Now I plunged into the python shell and requested an account to make sure that date_due has a datetime.date object on it, that is. I use Jinja to create my interface, so I considered creating a template filter, but I don’t know how this will work with wtforms, and it looks like sqlalchemy is the one who suffocates anyway.

And what is he doing? I'm sure I just need to figure out how to turn this datetime.date object into a string, but I'm not sure how to do this.

Halp. Thanks!

Edit: Here is the BillForm class:

 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()]) 

And the display class too:

 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
source share
1 answer

And it took me a while to figure out where you did wrong, but think that I found it. Here is your code:

 @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) 

Now, if you pass the class as obj kwarg to BillForm, the form is populated with all kinds of weird objects. For example, if I replicate what you have done and checking form.date_due.data , it says that it is an object <sqlalchemy.orm.attributes.InstrumentedAttribute at 0x277b2d0> . As with the error message, this object does not have the strftime attribute.

So, your mistake is indicated on line 5 of the code you submitted. If you want to fill out the form with the details of the account object you received in line 4, replace line 5 with form = BillForm(obj=bill) . As you can see, the “subtle” difference is the lowercase b in the score. I repeated your code, and I am convinced that it should fix the problem.

If you're interested, I usually do the editing.

 @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) 

I have not used SQLAlchemy for a while, so I could make a couple of mistakes there. Hope this helps! If this answers your question, accept the answer.

+5
source

Source: https://habr.com/ru/post/1481965/


All Articles