Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble rendering listfield model_form on mongoengine

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 below

class Post(db.Document):
    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)
    body = db.StringField(required=True)
    views = db.IntField(default=0)
    category = db.StringField()
    tags = db.ListField(db.StringField(max_length=30))

template

{% 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.type == 'ListField' %}
    {% for subfield in field.entires %}
         {% if subfield.type == 'StringField' %}
             {{ field }}
         {% endif %}
    {% endfor %}
    {% elif field.name == "body" %}
        {{ field(rows=10, style="width:360px;") }}
{% 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 %}

admin.py

from flask import Blueprint, request, redirect, render_template, url_for
from flask.views import MethodView
from pprint import pprint
from flask.ext.mongoengine.wtf import model_form

from tumblog.auth import requires_auth
from tumblog.models import Post

admin = Blueprint('admin', __name__, template_folder='templates')


class List(MethodView):
    decorators = [requires_auth]
    cls = Post

    def get(self,slug=None):
        posts = self.cls.objects.all()
        return render_template('admin/list.html', posts=posts)

class delList(MethodView):
    decorators = [requires_auth]
    cls = Post

    def get(self,slug=None):
        try:
            post = self.cls.objects.get(slug=slug)
            post.delete()
        except:
            pass
        return redirect(url_for('admin.index'))

class Detail(MethodView):

    decorators = [requires_auth]

    def get_context(self, slug=None):
        form_cls = model_form(Post, exclude=('created_at', 'views'))

        if slug:
            post = Post.objects.get_or_404(slug=slug)
            if request.method == 'POST':
                form = form_cls(request.form, inital=post._data)
            else:
                form = form_cls(obj=post)
        else:
            post = Post()
            form = form_cls(request.form)

        context = {
            "post": post,
            "form": form,
            "create": slug is None
        }
        return context

    def get(self, slug):
        context = self.get_context(slug)
        return render_template('admin/detail.html', **context)

    def post(self, slug):
        context = self.get_context(slug)
        form = context.get('form')

        if form.validate():
            post = context.get('post')
            form.populate_obj(post)
            post.save()

            return redirect(url_for('admin.index'))
        return render_template('admin/detail.html', **context)


# Register the urls
admin.add_url_rule('/admin/', view_func=List.as_view('index'))
admin.add_url_rule('/admin/create/', defaults={'slug': None}, view_func=Detail.as_view('create'))
admin.add_url_rule('/admin/edit/<slug>/', view_func=Detail.as_view('edit'))
admin.add_url_rule('/admin/delete/<slug>/', view_func=delList.as_view('delete'))
like image 622
user1695285 Avatar asked Dec 31 '13 05:12

user1695285


1 Answers

Because list fields may have their own special types for each item, you may need to define custom fields; or you can try to use wtforms.fields.FieldList directly.

It is difficult to say which error you are hitting; you can try to put information into the form for debugging, e.g.

{% for field in form %}
    <!-- {{field.type}} {{field.label}} -->
    ... etc ...
{% endfor %}

Also noticed you had a typo

{% for subfield in field.entires %} <=== did you mean field.entries ?

bounty question:

Unless you define help_text when declaring your field, this will not work as expected:

{{ field.help_text }}

You need to include it when declaring your fields, e.g.

oid = ObjectIdField(..., help_text="object id")
like image 159
dnozay Avatar answered Nov 02 '22 18:11

dnozay