python - WTForms: setting default value from an SQLAlchemy field with relationship -


there many questions here on titles sound similar i'm describe far can tell literally hours of research, question unique. here goes!

i'm writing first flask app. i'm using sqlalchemy model layer , wtforms handle forms. app going lightweight personal finance manager not use for serious biz. have 1 table list of transactions , expense categories (groceries, clothing, etc). transaction table has column ("category") references category table. in view, represent list of categories element.

my issue when editing transaction, can't figure out how tell wtforms set element specific pre-defined value. (yes, know can set default value @ time form defined, not asking.)

the model looks (with irrelevant fields removed):

class category(db.model):     id = db.column(db.integer, primary_key=true)     name = db.column(db.string(80), nullable=false, unique=true)     # ...  class trans(db.model):     # ...     category_id = db.column(db.integer, db.foreignkey('category.id'))     category = db.relationship('category',                                 backref=db.backref('trans', lazy='dynamic'))     # ... 

forms.py:

def category_choices():     return [('0', '')] + [(c.id, c.name) c in category.query.all()]  class transactionform(form):     # ...     category = selectfield('category', coerce=int, validators=[inputrequired()])     # ... 

the route (post not yet implemented):

@app.route('/transactions/edit/<trans_id>', methods=['get', 'post']) def trans_edit(trans_id):     transaction = trans.query.get(trans_id)     form = forms.transactionform(obj=transaction)     form.category.choices = forms.category_choices()     form.category.default = str(transaction.category.id)     #raise exception # debugging     return render_template('trans.html',                            title='edit transaction',                            form=form) 

and finally, template (jinja2):

{{ form.category(class='trans-category input-medium') }} 

as can see in route, set form.category.default transaction.category.id, doesn't work. think issue i'm setting "default" after form has been created. i'm rather forced because model comes database via sqlalchemy. root cause seems form.category object (due relationship), wtforms can't seem handle easily. can't have been first 1 come across this... need rework model more wtforms compatible? options?

thanks!

i alluded in comment. sounds might benefit using wtform's sqlalchemy extension. create dropdown list categories in trans form.

my example's use case different. relating blog post's topic. is, many posts share 1 topic. image in case, many transactions share 1 category.

form

from wtforms.ext.sqlalchemy.fields import queryselectfield  #import ext.  def enabled_topics(): # query topics (a.k.a categories)     return topic.query.all()  class postform(form):  # create form     title = stringfield(u'title', validators=[datarequired()])     body = stringfield(u'text', widget=textarea())     topic = queryselectfield(query_factory=enabled_topics, allow_blank=true) 

models important part here a) making sure have relationship correctly defined, , b.) adding topic init since use create new entry.

class post(db.model):     id = db.column(db.integer, primary_key=true)     title = db.column(db.string(80))     body = db.column(db.text)     # one-to-many topic     topic = db.relationship('topic', backref=db.backref('post', lazy='dynamic'))  def __init__(self, title, body, topic):         self.title = title         self.body = body         self.topic = topic  class topic(db.model):     id = db.column(db.integer, primary_key=true)     name = db.column(db.string(50))      def __init__(self, name):         self.name = name 

view nothing special here. regular view generates form , processes submitted results.

@app.route('/create', methods=['get', 'post']) @login_required def create_post():     form = postform()     if form.validate_on_submit():         post = post(title=form.title.data, body=form.body.data,                     topic=form.topic.data)         db.session.add(post)         db.session.commit()         topic.update_counts()         flash('your post has been published.')         return redirect(url_for('display_post', url=url))     posts = post.query.all()     return render_template('create_post.html', form=form, posts=posts) 

template nothing fancy here either. sure render field in template basic field. no fancy loop required since wtforms sqlalchemy extensions you.

{% extends "base.html" %} {% block title %}create/edit new post{% endblock %} {% block content %} <h3>create/edit post</h3> <form action="" method=post>    {{form.hidden_tag()}}    <dl>       <dt>title:       <dd>{{ form.title }}       <dt>post:       <dd>{{ form.body(cols="35", rows="20") }}       <dt>topic:       <dd>{{ form.topic }}    </dl>    <p>       <input type=submit value="publish"> </form> {% endblock %} 

that's it! post form has topic dropdown list. use terminology, when load transaction default category transaction highlighted in dropdown list. correct way state category associated transaction loaded via relationship defined in trans model.

also note, there multisellect sqlalchemy extension in case 1 transaction has many 'default' categories.

now, issue how deal many-to-many relationships.... i'm trying pass string of tags stored in many-to-many table textarea field. no sqlalchemy extension that!

i posted question here


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

inno setup - TLabel or TNewStaticText - change .Font.Style on Focus like Cursor changes with .Cursor -