Question

Why Flask + Mongoengine doesnot allow to show db items that is not fully correspond to db schema model?

Here is my class Tweet (in models.py of Flask app) inherited from Post, text and lang fields are named the same, as they come from Twitter API with every tweet.

class Tweet(Post):
    text = db.StringField(required=True)
    lang = db.StringField(max_length=255, required=True)

When i am saving Tweet post via admin it is saved to Mongodb, and i can render it in list.html:

{% for tweet in tweets %}
<b>Tweets list</b>
  <h2><a href="{{ url_for('posts.detail', slug=tweet.slug) }}">{{ tweet.text }}</a></h2>

    {% if tweet.post_type == 'Tweet' %}
        <b>{{ tweet.text }}</b>
        <p>{{ tweet.lang }}</p>
    {% endif %}
{% endfor %}

The problem: in that collection i stored a lot of full tweets with all fields, and all these tweets has text and lang fields, but it is not showed in browser. I mined tweets with external script and now want to use Flask to query existing collection to show tweets in web interface. And i don't want to define all tweet structure in ORM.

I have Robomongo and i see manually added from admin posts near the tweets, mined by Twitter python library. Fields are named "text" and "lang" because in tweet JSON they are named the same.

Was it helpful?

Solution

Ensure that a Tweet is a DynamicDocument and then loop the Tweet._dynamic_fields attribute to get the name of any dynamic fields.

Something like:

{% for tweet in tweets %}
<b>Tweets list</b>
  <h2><a href="{{ url_for('posts.detail', slug=tweet.slug) }}">{{ tweet.text }}</a></h2>

    {% if tweet.post_type == 'Tweet' %}
        <b>{{ tweet.text }}</b>
        <p>{{ tweet.lang }}</p>
        {% for field in tweet._dynamic_fields -%}
            <p>{{ tweet[field] }}</p>
        {%- endfor %}
    {% endif %}
{% endfor %}

Thats untested and I'm not 100% sure on how you dynamically get an attr in jinja2.

OTHER TIPS

Answer by Ross is correct, i wish now to clarify the process to get all working.

  1. I guessed that if a JSON document has an "_cls" : "Post.Tweet" attr it shows. The problem was that in tweets i mined no such attribute. I have added it to existing tweet using Robomongo for testing and it now appears in the list, near the simple manually added items!

  2. Before it shows i solved another error: i needed to map models to tweet structure so i need the tweet have a slug, for this i added "slug" : "Detective".

Result is showed, but nested JSON objects appears as clunky json mess.

The question now is how do achieve the same result without changing mined tweets, i need to change code: avoid checking _cls for tweets and setup slug to some existing field.

So what parts of code should i change&?

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