Google AppEngine: Form handling 'repeated'

2019-03-06 09:01发布

问题:

How do I work with ndb.StructuredProperty(repeated = True) properties when it comes to designing their forms and handlers? Consider this example:

I've got 3 ndb.Model kinds: SkilledPerson, his Education, and his (work) Experience. The latter two are StructuredProperty types of SkilledPerson.

class SkilledPerson(ndb.Model):
    name = ndb.StringProperty()
    birth = ndb.DateProperty()
    education = ndb.StructuredProperty(Education, repeated = True)
    experience = ndb.StructuredProperty(Experience, repeated = True)

class Education(ndb.Model):
    institution = ndb.StringProperty()
    certification = ndb.StringProperty()
    start = ndb.DateProperty()
    finish = ndb.DateProperty()

class Experience(ndb.Model):
    job_title = ndb.StringProperty()
    workplace = ndb.StringProperty()
    start = ndb.DateProperty()
    finish = ndb.DateProperty()

How would I create a form for the Skilled Person entity? It would display simple fields such as name and birth (StringProperty and DateProperty). Additionally, it must display a 'group' of fields for the Education and Experience StructuredProperty properties. I would imagine the form to look something like this:

<form method="post">

<h2>Skilled Person Form</h2>

    <label>Name<br> 
        <input type="text" name="name" value="{{name}}">
    </label>


    <label>Birth<br> 
        <input type="date" name="birth" value="{{birth}}">
    </label>


    <!-- Education form goes here -->

    <!-- and Experience form goes here -->

    <input type="submit">

</form>

How do I include the groups of fields for Education and Experience in this form?

An example Education form:

<form method="post">

<h2>Add Education</h2>

    <label>Institution<br> 
        <input type="text" name="institution" value="{{institution}}">
    </label>

    <label>Certification<br> 
        <input type="text" name="certification" value="{{certification}}">
    </label>

    <label>Start<br> 
        <input type="date" name="start" value="{{start}}">
    </label>

    <label>Finish<br> 
        <input type="date" name="finish" value="{{finish}}">
    </label>

    <input type="submit">

</form>

回答1:

Using Jinja2 you can create a loop to generate the HTML for each Education and for each Experience.

You can use the special Jinja variable loop.index to assign unique names like education-1...education-4: "name-{{ loop.index }}"

If you need a lot of form processing and validation, you can use WTForms. See the docs: http://wtforms.readthedocs.org/en/latest/crash_course.html

And if you need to change the lists of Educations and Experiences in your form, you have to use javascript and jquery to add new items (form fields) or to delete items (form fields).