Question

I am using Flask, mongoengine for a project and I am trying to get basic stuff working from http://docs.mongodb.org/manual/tutorial/write-a-tumblelog-application-with-flask-mongoengine/

After implementing everything from above link I added a new field for "tags" in Post and when I try to create a post, my tags doesn't show a input box.

Any help is appreciated.

My code and screenshot below

class Post(db.DynamicDocument):
    created_at = db.DateTimeField(default=datetime.datetime.now, required=True)
    title = db.StringField(max_length=255, required=True)
    slug = db.StringField(max_length=255, required=True)
    comments = db.ListField(db.EmbeddedDocumentField('Comment'))
    tags = db.ListField(db.StringField(max_length=30)) # New field I added

enter image description here

enter image description here

template form

{% macro render(form) -%}
<fieldset>
{% for field in form %}
{% if field.type in ['CSRFTokenField', 'HiddenField'] %}
   {{ field() }}
{% else %}
  <div class="clearfix {% if field.errors %}error{% endif %}">
    {{ field.label }}
    <div class="input">
      {% if field.name == "body" %}
        {{ field(rows=10, cols=40) }}
      {% else %}
        {{ field() }}
      {% endif %}
      {% if field.errors or field.help_text %}
        <span class="help-inline">
        {% if field.errors %}
          {{ field.errors|join(' ') }}
        {% else %}
          {{ field.help_text }}
        {% endif %}
        </span>
      {% endif %}
    </div>
  </div>
{% endif %}
{% endfor %}
</fieldset>
{% endmacro %}

rendering form code

{% extends "admin/base.html" %}
{% import "_forms.html" as forms %}

{% block content %}
<h2>
  {% if create %}
  Add new Post
  {% else %}
  Edit Post
  {% endif %}
</h2>

<form action="?{{ request.query_string }}" method="post">
  {{ forms.render(form) }}
  <div class="actions">
    <input type="submit" class="btn primary" value="save">
    <a href="{{ url_for("admin.index") }}" class="btn secondary">Cancel</a>
  </div>
</form>
{% endblock %}
Was it helpful?

Solution

From what I can gather, your problem is you're telling WTF to render the tags field, but WTForms doesn't know how to handle that information.

From looking at the Flask-MongoEngine documentation, it seems the ListField is just a FieldList as WTForms refers to it.

Currently you're not actually defining the form independently in WTForms, you're just using the magic included in Flask-MongoEngine, so my first attempt would be to add some more logic to your macro, add a {% elif field.type == 'ListField' %} and try and discover what's contained in there to iterate through to produce your form. From having a quick look at the source-code, something like the following might work.

{% elif field.type == 'ListField %}
    {# render_the_group_label #}
    {% for subfield in field.entries %}
        {% if subfield.type == 'StringField' %}
            {# render_the_subfield #}
        {% endif %}
    {% endfor %}
...

That code will need to be worked on, but hopefully it'll point you in the right direction. Otherwise, I'd actually define the form seperately in WTForms to give you a bit more control on the code-side. Luckily they provide a csv tag example which should help you if you need to go that route. I wrote a guide that takes a different route using @property decorators to achieve a similar effect, which again, might at least point you towards the finish line.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top