2014-04-08 32 views
8

Oto moje rozwijane menu HTML. Wartość jest kluczem podstawowym tabeli podrzędnej.Kompletny przykład "wiele do jednego" za pomocą kolby, WTForm, SQLAlchemy i 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> 

Muszę zaktualizować parametr Post.category_id wartością całkowitą 1 zamiast "Kategoria numer jeden". Oto mój kod.

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

Próbowałem podejmowania ...

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

Teraz nie byłoby to miłe!

+0

Rozwiązałem problem ... Używam WT Forms QuerySelectField, więc moim błędem było myślenie, że muszę dodać pole category_id do szablonu jija2 .... Rozszerzenie WTF obsługuje to wszystko dla ciebie. Więc ... Wszystko, co musisz zrobić, to martwić się o pole kategorii. Dotyczy to widoku, szablonu i modelu. – jwogrady

Odpowiedz

7

Wymyśliłem! Oto moje rozwiązanie. Mam nadzieję, że ten zapis pomoże drugiemu facetowi.

Rozwiązaniem jest umożliwienie przedłużenia wykonania pracy za Ciebie! Oto działający przykład rozszerzenia WT Forms sqlalchemy za pomocą Flask, WTForm, SQLAlchemy i Jinja2. W skrócie, nie musisz martwić się o identyfikator child, ponieważ rozszerzenie zajmuje się nim automagicznie. Oznacza to, że gdy masz do czynienia z modelami SQLAlchemy Parent i Child w relacji jeden do wielu, TYLKO musisz zajmować się PARENTEM.

MODEL

Po pierwsze, upewnij się, że twój model i relacje są poprawne. Zauważ w moim przykładzie, jak zdefiniowane są relacje i czy model tego modelu ma tylko CATEGORY ... NOT CATEGORY_ID. Mój błąd polegał na tym, że zapełniłem pole CATEGORY_ID mojego modelu. Nie. Rozszerzenie robi to za Ciebie. W rzeczywistości, jeśli spróbujesz zrobić to ręcznie jak ja to nie będzie działać w ogóle ....

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 

drugie, należy sprawdzić formularz .... UWAGA Używam wtfrom sqlalchmey QuerySelectedField a pole category_id jest nieobecny ...

FORMULARZ

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) 

teraz logika KOLBY routingu i widok ... Wskazówki na stanowiskach NO ponownie category_id! Tylko kategoria !!!

trasowania/WIDOK

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

Wreszcie szablon. Zgadnij co, generujemy tylko pole form.category !!!

WZÓR

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

... Wynik to rozwiązanie poprawnie wykorzystuje model kategorię jako tabeli odnośników i łączy prawidłowo wiersze post przez pisanie liczb całkowitych Kategoria PK w dziedzinie Posty category_id. Yeeeehaww!