Вопрос

I'm new at GAE and all that python stuff, so question might be stupid at last.)

I have model:

from google.appengine.ext import db

class Task(db.Model):
    name = db.StringProperty()
    summary = db.StringProperty(multiline=True)

and I want to auto generate form, so:

import webapp2
import jinja2
import os

from wtforms.ext.appengine.db import model_form

from Tasks.model import Task

jinja_environment = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__) + '/../templates/admin'))

class AddTaskPage(webapp2.RequestHandler):
    def get(self):

        AddForm = model_form(Task)
        template_values = {
            'form_self_link': self.request.path,
            'form_content': AddForm
        }

        template = jinja_environment.get_template('add_task.html')
        self.response.out.write(template.render(template_values))

add_task.html template:

<form method="POST" action="{{form_self_link}}">
    {{form_content}}
    <input type="submit" value="Add">
</form>

And the most confusing is output – 

<form method="POST" action="/admin/tasks/add">
    <class 'wtforms.ext.appengine.db.TaskForm'>
    <input type="submit" value="Добавить">
</form>

There is NO form's elements, there is just very strange <class 'wtforms.ext.appengine.db.TaskForm'> stuff.

I use GAE 1.6.1, python 2.7.2, jinja 2.6 (bundled with GAE), WTForms 0.6.3 (latest)

Could you please help?

UPDATE: I've used instruction bundled with class and it is not working:

   from google.appengine.ext import db
   from tipfy.ext.model.form import model_form

   # Define an example model and add a record.
   class Contact(db.Model):
       name = db.StringProperty(required=True)
       city = db.StringProperty()
       age = db.IntegerProperty(required=True)
       is_admin = db.BooleanProperty(default=False)

   new_entity = Contact(key_name='test', name='Test Name', age=17)
   new_entity.put()

   # Generate a form based on the model.
   ContactForm = model_form(Contact)

   # Get a form populated with entity data.
   entity = Contact.get_by_key_name('test')
   form = ContactForm(obj=entity)

The only strange moment is "from tipfy.ext.model.form import model_form" string, but I think it is just an error in docs.

UPDATE 2

Well I managed to get it work and may be I missed something, seems like there is no feature "auto print form" in WTForm. So it works now like that:

class AddTaskPage(webapp2.RequestHandler):
    def get(self):
        AddForm = model_form(Task)()
        template_values = {
            'form_self_link': self.request.path,
            'form_name_field': AddForm.name
        }

        template = jinja_environment.get_template('add_task.html')
        self.response.out.write(template.render(template_values))

And prints out

<form method="POST" action="/admin/tasks/add">
    <input id="name" name="name" type="text" value="">
    <input type="submit" value="Добавить">
</form>

Well... seems like the only option is to do something like in future (taken from docs)

<form method="POST" action="/...">
    <div>{{ form.username.label }}: {{ form.username(class="css_class") }}</div>
    <div>{{ form.password.label }}: {{ form.password() }}</div>
<!-- and so on .... -->
</form>

Is it really no any auto-generate and auto-print form libraries for GAE with Python 2.7?(

LAST UPDATE

Well... I found one option to get it work and render all form elements:

class AddTaskPage(webapp2.RequestHandler):
    def get(self):
        addForm = model_form(Task)()
        template_values = {
            'form_self_link': self.request.path,
            'form': addForm
        }

        template = jinja_environment.get_template('add_task.html')
        self.response.out.write(template.render(template_values))

    def post(self):
        addForm = model_form(Task)(self.request.POST)
        template_values = {
            'form_self_link': self.request.path,
            'form': addForm
        }

        template = jinja_environment.get_template('add_task.html')
        self.response.out.write(template.render(template_values))

In template:

{% for field in form %}
    <tr>
        <th>{{ field.label }}</th>
        <td>{{ field }}</td>
    </tr>
{% endfor %}

Looks not so bad .)

Это было полезно?

Решение

I think you have to pass AddForm.content as a template value (instead of AddForm)

template_values = {
        'form_self_link': self.request.path,
        'form_content': AddForm**.content**
}

UPDATE

found this in the docs (http://wtforms.simplecodes.com/docs/0.6.1/ext.html#wtforms.ext.appengine.db.model_form)

wtforms.ext.appengine.db.model_form(model)

Creates and returns a dynamic wtforms.Form class for a given db.Model class. The form class can be used as it is or serve as a base for extended form classes...

So what you are passing into the template is the class, not an instance of it.

AddForm = model_form(Task)()
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top