2014-04-08 11 views
8

Ecco il menu a discesa HTML. Il valore è la chiave primaria della tabella figlio.Un esempio completo di molti con Flask, WTForm, SQLAlchemy e Jinja2

<select id="category" name="category"> 
    <option selected value="__None"></option> 
    <option value="1">Category Number One</option> 
    <option value="2">Category Number Two</option> 
</select> 

ho bisogno di aggiornare Post.category_id con l'intero valore di 1 posto di "Categoria Numero Uno". Ecco il mio codice.

# create new post 
@app.route('/admin/post', methods=['GET', 'POST']) 
@login_required # Required for Flask-Security 
def create_post(): 
    form = PostForm() 
    if form.validate_on_submit(): 
     post = Post(title=form.title.data, 
        body=form.body.data, 
        pub_date=form.pub_date.data, 
        cateogry_id=form.category.data) 
     db.session.add(post) 
     db.session.commit() 
     flash('Your post has been published.') 
     return redirect(url_for('admin')) 
    posts = Post.query.all() 
    return render_template('create_post.html', form=form, posts=posts) 

Ho provato a fare ...

cateogry_id=form.category.data 
cateogry_id=form.category.value 

Ora, non sarebbe bello!

+0

Ho risolto il problema ... Sto usando il modulo QuerySelectField di WT Form in modo che il mio errore fosse pensare che dovevo aggiungere il campo category_id al modello jija2 .... L'estensione WTF gestisce tutto ciò che fa per te. Quindi ... Tutto quello che devi fare è preoccuparti del campo categoria. Questo vale per la vista, il modello e il modello. – jwogrady

risposta

7

L'ho capito! Ecco la mia soluzione. Speriamo che questo articolo possa aiutare il prossimo ragazzo.

La soluzione è lasciare che l'estensione faccia il lavoro per te! Ecco un esempio funzionante dell'estensione sqlalchemy di WT Forms che utilizza Flask, WTForm, SQLAlchemy e Jinja2. In breve, non è necessario preoccuparsi dell'ID figlio perché l'estensione si prende cura di esso automaticamente. ciò significa che quando si ha a che fare con i modelli genitore e figlio di SQLAlchemy in una relazione uno a molti, si deve trattare SOLO con il GENITORE.

MODELLO

Per prima cosa, assicurarsi che il vostro modello e le relazioni siano corrette. Notare nel mio esempio come sono definite le relazioni e che l'init del modello ha solo CATEGORY ... NON CATEGORY_ID. Il mio errore era pensare che avrei compilato il campo CATEGORY_ID del mio modello. No. L'estensione lo fa per te. In realtà, se si tenta di farlo manualmente come ho fatto io non funzionerà affatto ....

class Post(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    title = db.Column(db.String(80)) 
    url = db.Column(db.String(120)) 
    body = db.Column(db.Text) 
    create_date = db.Column(db.DateTime) 
    pub_date = db.Column(db.DateTime) 
    pub_status = db.Column(db.Text(80)) 
    author_id = db.Column(db.Integer, db.ForeignKey('user.id')) 
    author = db.relationship('User', 
          backref=db.backref('posts', lazy='dynamic')) 
    category_id = db.Column(db.Integer, db.ForeignKey('category.id')) 
    category = db.relationship('Category', 
           backref=db.backref('posts', lazy='dynamic')) 

    def __init__(self, title, body, category, pub_date=None): 
     self.title = title 
     self.body = body 
     if pub_date is None: 
      pub_date = datetime.utcnow() 
     self.category = category 
     self.pub_date = pub_date 

    def __repr__(self): 
     return '<Post %r>' % self.title 

class Category(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(50)) 
    description = db.Column(db.String(250)) 

    def __init__(self, name): 
     self.name = name 

    def __repr__(self): 
     return self.name 

secondo luogo, verificare il modulo .... AVVISO sto usando il wtfrom sqlalchmey QuerySelectedField e il campo category_id è assente ...

FORM

from sprucepress.models import Tag, Category 
from flask_wtf import Form 
from wtforms.fields import StringField, DateTimeField 
from wtforms.widgets import TextArea 
from wtforms.validators import DataRequired 
from wtforms.ext.sqlalchemy.orm import model_form 
from wtforms.ext.sqlalchemy.fields import QuerySelectField 


def enabled_categories(): 
    return Category.query.all() 


class PostForm(Form): 
    title = StringField(u'title', validators=[DataRequired()]) 
    body = StringField(u'Text', widget=TextArea()) 
    pub_date = DateTimeField(u'date create') 
    category = QuerySelectField(query_factory=enabled_categories, 
           allow_blank=True) 

Ora la logica BOCCETTA di routing e vista ... Avviso in post NO nuovo category_id! Solo la categoria solo !!!

routing/VISTA

# create new post 
@app.route('/admin/post', methods=['GET', 'POST']) 
@login_required # required for Flask-Security 
def create_post(): 
    form = PostForm() 
    if form.validate_on_submit(): 
     post = Post(title=form.title.data, pub_date=form.pub_date.data, 
        body=form.body.data, category=form.category.data) 
     db.session.add(post) 
     db.session.commit() 
     flash('Your post has been published.') 
     return redirect(url_for('admin')) 
    posts = Post.query.all() 
    return render_template('create_post.html', form=form, posts=posts) 

Infine, il modello. Indovina, generiamo solo il campo forma.categoria !!!

MODELLO

<form action="" method=post> 
    {{form.hidden_tag()}} 
    <dl> 
     <dt>Title: 
     <dd>{{ form.title }} 
     <dt>Post: 
     <dd>{{ form.body(cols="35", rows="20") }} 
     <dt>Category: 
     <dd>{{ form.category }} 

    </dl> 
    <p> 
     <input type=submit value="Publish"> 
    </form> 

Il risultato ... Questa soluzione utilizza correttamente il modello Categoria come una tabella di ricerca e associa le righe post correttamente scrivendo i numeri interi Categoria PK al campo Messaggi category_id. Yeeeehaww!