EzDevInfo.com

wtforms

A flexible forms validation and rendering library for Python. WTForms Documentation — WTForms 2.0.3dev documentation

Wtforms, add a class to a form dynamically

is there a way i could send a form's (css) class from python? For example:

class Company(Form):
    companyName = TextField('Company Name', [validators.Length(min=3, max = 60)])

This renders a simple text field, but i want that text field to have the css class of .companyName, is that possible directly from python?

I know that i can put a id="companyName" directly from python, but not class.

Help.

Update: I tried class_="companyName" and it did not work, i got:

__init__() got an unexpected keyword argument '_class'

Source: (StackOverflow)

Using FieldList and FormField

We have the following forms and we are trying to create list of GroupRoleForms for each group.

class FullNameMixIn():
    full_name = TextField(
        'Full name', [
            validators.required(message=u"Full name is required")
        ])

class GroupRoleForm(Form):
    group =BooleanField('Group', default=False)
    role = SelectField(
            'Role',choices=[
            ("none", "----------"), 
            ('approver', 'Approver'),
            ('editor', 'Editor')
            ])

class AdminEditUserForm(Form, FullNameMixIn):
    group_roles = FieldList(FormField(GroupRoleForm))

How can we create a AdminEditUserForm instance that contains a pre-populated list of GroupRoleForms?

At the moment we are trying to do it this way:

form = forms.AdminEditUserForm()
for group in  company.groups:
    group_role_form = forms.GroupRoleForm()
    group_role_form.group.label =  group.name
    group_role_form.group.name = group.id
    form.group_roles.append_entry(group_role_form)
return dict(edit_user_form = form )

Source: (StackOverflow)

Advertisements

Flask-SQLAlchemy: How to conditionally insert or update a row

My application uses a combination of Flask, Flask-SQLAlchemy, Flask-WTF and Jinja2.

In its current incarnation, I have a settings table. The table will only have one record with one field. Initially the table contains zero records.

What I want to achieve is:

  • Given that no entries exist in db, then show empty form ready for user input
  • Given that an entry exist, show the entry, and
  • if the user changes the value, then update the rec in db.

Here is my code:

models.py

class Provider(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    rssfeed = db.Column(db.String(120), unique = True)

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

    def __repr__(self):
        return '<NZBMatrix feed url %r>' % self.rssfeed

forms.py

class SettingsForm(Form):
    rssfeed = TextField('rssfed', validators= [Required()])

views.py

    @app.route('/settings', methods=["GET","POST"])
    def settings():
    """ show settings """
        provider = Provider.query.get(1)
        form = SettingsForm(obj=provider)
        print provider

        if request.method == "POST" and form.validate():
            if Provider.query.get(1) is None:
                provider = Provider(rssfeed=form.rssfeed.data)
                form.populate_obj(provider)
                db.session.add(provider)
                db.session.commit()
                flash("Settings added")

        return render_template("settings.html", form=form)

As it stands this code creates a record if it doesn't exists but the rssfeed column is empty.

How can I change this code so that it will INSERT if the record doesn't exist and UPDATE if it does?


Source: (StackOverflow)

Flask-WTF - validate_on_submit() is never executed

I'm using Flask-WTF:

Here is my form:

from flask.ext.wtf import Form, TextField

class BookNewForm(Form):
    name = TextField('Name')

Here is the controller:

@book.route('/book/new', methods=['GET', 'POST'])
def customers_new():
    form = BookNewForm()
    if form.is_submitted():
        print "submitted"
    if form.validate():
        print "valid"
    if form.validate_on_submit():
        flash("Successfully created a new book")
        return redirect(url_for('.books_show'))
    return render_template('views/books_new.html', form=form)

Now the problem is, if you look at my print statements, it always prints submitted, but it NEVER prints valid and validate_on_submit() is never executed. Why?


Source: (StackOverflow)

Disabled field is considered for validation in WTForms and Flask

I have some fields in page disabled as for example:(using jinja2 templating system)

<html>
<body>
<form action="" method=POST>
    {{ form.name(disabled=True) }}
    {{ form.title }}
    -- submit button --
</form>
</body>
</html>

Field is disabled in the form as expected.

In my views.py: On doing validate_on_submit() on form submit, it fails with validation error on 'name' field which is disabled. I was hoping that validation ignores disabled field. Is it the right behaviour? If so, can you please let know how to handle such a case?

Updated:

class TeamForm(wtf.Form):
    name = wtf.TextField("Team Name", validators=[validators.Required()])
    title = wtf.TextField("Title", validators=[validators.Required()])

Source: (StackOverflow)

Pylint - Pylint unable to import flask.ext.wtf?

I've got my Pylint install importing flask just fine. And with that same installation of flask, I have wtforms running just fine in my application. However, when I run Pylint on a file importing wtforms:

from flask.ext import wtf
from flask.ext.wtf import validators

class PostForm(wtf.Form):
    content = wtf.TextAreaField('Content', validators=[validators.Required()])

From Pylint I get:

E:  1,0: No name 'wtf' in module 'flask.ext'
E:  2,0: No name 'wtf' in module 'flask.ext'
F:  2,0: Unable to import 'flask.ext.wtf'

While searching around I found this discussion suggesting it may be because flask.ext libraries are actually just "shortcuts" to libraries.

Any idea of how I can fix this? Thank you much!


Source: (StackOverflow)

Setting a default value in the selectfield, using wtforms and flask

I am creating a product edit form and I need the form to be pre-populated with the previous data.

I am doing the following:

Product(form):
    product = TextField('name')
    category = SelectField('category', choice=[(1,'one'),(2,'two')])

In the view:

form.product.data = 'A product name from the database'
form.category.data = 'a category name' #This does not work

The issue is with the SelectField.

I understand there is a 'default' value I can set on SelectField. However, this happens in the form definition class and there I do not have the query object from sqlalchemy yet.

So, is there a way to append a default on selectfield on run time?


Source: (StackOverflow)

wtforms hidden field value

I am no programmer, so please be gentle with me. I am using WTForms, quite successfully, but I have a problem with hidden fields not returning values, whereas the docs say they should. I have constructed a simple example, hope this is clear;

forms.py:

from wtforms import (Form, TextField, HiddenField)

class TestForm(Form):
    fld1 = HiddenField("Field 1")
    fld2 = TextField("Field 2")

experiment.html:

{% from "_formshelper.html" import render_field %}
<html>
    <body>
        <table>
        <form method=post action="/exp">
            {% for field in form %}
                {{ render_field(field) }}
            {% endfor %}
            <input type=submit value="Post">
        </form>
        </table>        
    </body>
</html>

(render_field just puts the label, field and errors in td tags)

experiment.py:

from flask import Flask, request, render_template

from templates.forms import *
from introspection import *

app = Flask(\__name__)                  
app.config.from_object(\__name__)
db_session = loadSession()

@app.route('/exp', methods=['POST', 'GET'])
def terms():
    mydata = db_session.query(Peter).one()
    form = TestForm(request.form, mydata)
    if request.method == 'POST' and form.validate():
        return str(form.data)
    return render_template('experiment.html', form = form)

if __name__ == '__main__':
    app.run(debug = True)  

mydata returns the only row from a table that has 2 fields, fld1 and fld2. fld1 is an integer autoincrement field. The form is populated with that data, so if I run experiment.py, when I submit the form I get:

{'fld2': u'blah blah blah', 'fld1': u'1'}

But if I change fld1 to HiddenField, when I hit submit, I get: {'fld2': u'blah blah blah', 'fld1': u''}

What am I doing wrong? Thanks in anticipation.


Source: (StackOverflow)

How to model multilingual objects in Python using webapp2

I build a multilingual web app using Python and webapp2.

I have an object called Tag, which has translations to multiple languages. For this reason, I have created the following models:

class Language(ndb.Model):
    code = ndb.StringProperty()
    name = ndb.StringProperty(indexed=False)


class MultilingualText(ndb.Model):
    language = ndb.KeyProperty(kind=Language)
    text = ndb.TextProperty(indexed=False)


class Tag(ndb.Model):
    translations = ndb.StructuredProperty(MultilingualText, repeated=True, indexed=False)

I would like to ask if this is the correct way to do such task, and how this structure can be used along with WTForms for validation, etc.

Thanks a lot in advance!


Source: (StackOverflow)

How to render my TextArea with WTForms?

To render my textareafield with a specified number of columns and rows with WTForms, how do I set the number of columns and rows? I followed the instructions from this question but it didn't work:

How to specify rows and columns of a <textarea > tag using wtforms

I tried adding a widget but it didn't work:

class AForm(Form):
    name = TextField('Name', [validators.Length(min=4)])
    title = TextField('Title', [validators.Length(min=4)])
    text = TextAreaField('Text', widget=TextArea(row=70, cols=11))
    phonenumber = TextField('Phone number')
    phonenumberhide = BooleanField('Display phone number on site')
    price = TextField('Price')
    password = PasswordField('Password')
    email = TextField('Email', [
        validators.Length(min=6, message=_('Little short for an email address?')),
        validators.Email(message=_('That\'s not a valid email address.'))
    ])

TypeError: object.new() takes no parameters


Source: (StackOverflow)

I'm having problems with wtforms selectfields when i use a POST with Flask

I'm pretty new to wtforms and flask and was messing around with selectfields and got an error. The form itself works just fine without the selectfield but with it I get the following error:

Error:

....fields.py", line 386, in pre_validate
    for v, _ in self.choices: TypeError: 'NoneType' object is not iterable

I see the selectfield so it's being rendered. I suspect somehow the id is not being validated properly on POST and is returning none. Or it has something to do with my selectfield tuple being returned ? Also the ID field I'm using is pulled from GAE's ndb automatic key().id() which is rather long and obnoxious. It could be the id length being used for the selectfield is too long ?

Googling hasn't provided much in terms of the exact problem so thought I'd post here. Relevant code below. If I'm missing something please let me know

views.py code:

@app.route('/new/post', methods = ['GET', 'POST'])
@login_required
def new_post():

    form = PostForm()
    if form.validate_on_submit():
        post = Post(title = form.title.data,
                    content = form.content.data,
                    hometest = form.hometest.data,
                    author = users.get_current_user())
        post.put()
        flash('Post saved on database.')
        return redirect(url_for('list_posts'))
    form.hometest.choices = [ (h.key.id(),h.homename)for h in Home.query()]

    return render_template('new_post.html', form=form)

myforms.py:

class PostForm(Form):
    title = wtf.TextField('Title', validators=[validators.Required()])
    content = wtf.TextAreaField('Content', validators=[validators.Required()])
    hometest = wtf.SelectField(u'Home Name List', coerce=int,validators=[validators.optional()])

new_post.html:

{% extends "base.html" %}

{% block content %}
    <h1 id="">Write a post</h1>
    <form action="{{ url_for('new_post') }}" method="post" accept-charset="utf-8">
        {{ form.csrf_token }}
        <p>
            <label for="title">{{ form.title.label }}</label><br />
            {{ form.title|safe }}<br />
            {% if form.title.errors %}
            <ul class="errors">
                {% for error in form.title.errors %}
                <li>{{ error }}</li>
                {% endfor %}
            </ul>
            {% endif %}
        </p>
        <p>
            <label for="title">{{form.hometest.label}}</label><br/>
            {{form.hometest}}
            {% if form.hometest.errors %}
        <ul class="errors">
            {% for error in form.hometest.errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
        {% endif %}
        </p>
        <p>
            <label for="title">{{ form.content.label }}</label><br />
            {{ form.content|safe }}<br />

            {% if form.content.errors %}
            <ul class="errors">
                {% for error in form.content.errors %}
                <li>{{ error }}</li>
                {% endfor %}
            </ul>
            {% endif %}
        </p>
        <p><input type="submit" value="Save post"/></p>
    </form>
{% endblock %}

Source: (StackOverflow)

How to specify rows and columns of a