2016-01-24 69 views
1

我試圖將Flask Admin文本框變成CKEdit框,如此處所述。但是,當我運行它並轉到現有管理字段時,它不會顯示文本框的任何更改,並且當我運行它並轉到創建的TestAdmin字段以演示出此錯誤時:讓CKEditor與Flask Admin一起工作

OperationalError: (OperationalError) no such table: test u'SELECT count(?) AS count_1 \nFROM test' ('*',)

伴隨着一堆其他的回溯信息。

我已經改變了我的init腳本是這樣的:

import os 
from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy 
from flask.ext.login import LoginManager 
from flask.ext.openid import OpenID 
from flask.ext.mail import Mail 
from config import basedir, ADMINS, MAIL_SERVER, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD 
from momentjs import momentjs 
from flask.ext.babel import Babel 
from flask.ext import admin 
from flask_admin.contrib.sqla import ModelView 
from wtforms import TextAreaField 
from wtforms.widgets import TextArea 

app = Flask(__name__) 

app.config.from_object('config') 
db = SQLAlchemy(app) 
lm = LoginManager() 
lm.init_app(app) 
lm.login_view = 'login' 
oid = OpenID(app, os.path.join(basedir, 'tmp')) 
mail = Mail(app) 
babel = Babel(app) 

from app import views, models 


### 
class CKTextAreaWidget(TextArea): 
    def __call__(self, field, **kwargs): 
     if kwargs.get('class'): 
      kwargs['class'] += " ckeditor" 
     else: 
      kwargs.setdefault('class', 'ckeditor') 
     return super(CKTextAreaWidget, self).__call__(field, **kwargs) 

class CKTextAreaField(TextAreaField): 
    widget = CKTextAreaWidget() 


class Test(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    text = db.Column(db.UnicodeText) 


class TestAdmin(ModelView): 
    form_overrides = dict(text=CKTextAreaField) 

    create_template = 'edit.html' 
    edit_template = 'edit.html' 

admin = admin.Admin(app, name = 'PetroTools', template_mode = 'bootstrap3') 
admin.add_view(ModelView(models.Report, db.session)) 
admin.add_view(ModelView(models.Well, db.session)) 
admin.add_view(ModelView(models.Field, db.session)) 
admin.add_view(ModelView(models.Section, db.session)) 
admin.add_view(TestAdmin(Test, db.session)) 

if not app.debug: 
    import logging 
    from logging.handlers import SMTPHandler 
    credentials = None 
    if MAIL_USERNAME or MAIL_PASSWORD: 
     credentials = (MAIL_USERNAME, MAIL_PASSWORD) 
    mail_handler = SMTPHandler((MAIL_SERVER, MAIL_PORT), '[email protected]' + MAIL_SERVER, ADMINS, 'microblog failure', credentials) 
    mail_handler.setLevel(logging.ERROR) 
    app.logger.addHandler(mail_handler) 

if not app.debug: 
    import logging 
    from logging.handlers import RotatingFileHandler 
    file_handler = RotatingFileHandler('tmp/microblog.log', 'a', 1 * 1024 * 1024, 10) 
    file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')) 
    app.logger.setLevel(logging.INFO) 
    file_handler.setLevel(logging.INFO) 
    app.logger.addHandler(file_handler) 
    app.logger.info('microblog startup') 

app.jinja_env.globals['momentjs'] = momentjs 

,我已經把edit.html文件在我app/templates文件夾中。

我最好的猜測,爲什麼它不工作,也許我不應該把edit.html與其他東西放入模板文件夾,但在燒瓶管理模板文件夾?但該文件夾在哪裏?我甚至有嗎?在edit.html它說:

{% extends 'admin/model/edit.html' %}

但是我沒有這個目錄。這是什麼搞砸了嗎?

我想我可能做了一件非常愚蠢的事情,因爲我不瞭解這件事究竟如何改變ckeditor模板。誰能幫忙?

非常感謝,亞歷克斯

編輯:這裏是在edit.html文件的一切。我沒有編輯github的版本,我在文件夾/app/templates/

{% extends 'admin/model/edit.html' %} 

{% block tail %} 
    {{ super() }} 
    <script src="http://cdnjs.cloudflare.com/ajax/libs/ckeditor/4.0.1/ckeditor.js"></script> 
{% endblock %} 

最後編輯: 隨着坎寧安先生的幫助下,我最終版本的作品,看起來像這樣:

import os 
from flask import Flask 
from flask.ext.sqlalchemy import SQLAlchemy 
from flask.ext.login import LoginManager 
from flask.ext.openid import OpenID 
from flask.ext.mail import Mail 
from config import basedir, ADMINS, MAIL_SERVER, MAIL_PORT, MAIL_USERNAME, MAIL_PASSWORD 
from momentjs import momentjs 
from flask.ext.babel import Babel 

### 
from flask.ext import admin 
from flask_admin.contrib.sqla import ModelView 
from wtforms import TextAreaField 
from wtforms.widgets import TextArea 
### 

app = Flask(__name__) 

app.config.from_object('config') 
db = SQLAlchemy(app) 
lm = LoginManager() 
lm.init_app(app) 
lm.login_view = 'login' 
oid = OpenID(app, os.path.join(basedir, 'tmp')) 
mail = Mail(app) 
babel = Babel(app) 

from app import views, models 


### 
class CKTextAreaWidget(TextArea): 
    def __call__(self, field, **kwargs): 
     if kwargs.get('class'): 
      kwargs['class'] += " ckeditor" 
     else: 
      kwargs.setdefault('class', 'ckeditor') 
     return super(CKTextAreaWidget, self).__call__(field, **kwargs) 

class CKTextAreaField(TextAreaField): 
    widget = CKTextAreaWidget() 

class TestAdmin(ModelView): 
    form_overrides = dict(text=CKTextAreaField) 

    create_template = 'edit.html' 
    edit_template = 'edit.html' 


###ADMIN### 
admin = admin.Admin(app, name = 'PetroTools', template_mode = 'bootstrap3') 
admin.add_view(TestAdmin(models.Report, db.session)) 
admin.add_view(TestAdmin(models.Well, db.session)) 
admin.add_view(TestAdmin(models.Field, db.session)) 
admin.add_view(TestAdmin(models.Section, db.session)) 
########### 

if not app.debug: 
    import logging 
    from logging.handlers import SMTPHandler 
    credentials = None 
    if MAIL_USERNAME or MAIL_PASSWORD: 
     credentials = (MAIL_USERNAME, MAIL_PASSWORD) 
    mail_handler = SMTPHandler((MAIL_SERVER, MAIL_PORT), '[email protected]' + MAIL_SERVER, ADMINS, 'microblog failure', credentials) 
    mail_handler.setLevel(logging.ERROR) 
    app.logger.addHandler(mail_handler) 

if not app.debug: 
    import logging 
    from logging.handlers import RotatingFileHandler 
    file_handler = RotatingFileHandler('tmp/microblog.log', 'a', 1 * 1024 * 1024, 10) 
    file_handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')) 
    app.logger.setLevel(logging.INFO) 
    file_handler.setLevel(logging.INFO) 
    app.logger.addHandler(file_handler) 
    app.logger.info('microblog startup') 

app.jinja_env.globals['momentjs'] = momentjs 

起初,它仍然是沒有顯示的文本字段作爲管理員ckedit領域。我通過刪除所有表並重新創建它們並使用Miguel Grinberg的flask教程中的db_migrate.py腳本來實現它。我還將我的models.py文件中的文本字段從Text更名爲text,不確定是否有任何影響。

+0

你能告訴你所有的edit.html的。 – pjcunningham

+0

當然,我已經加入了它。 –

+0

如果你在TestAdmin類中註釋掉form_overrides,你會得到什麼? – pjcunningham

回答

2

這是一個使用內存中SQLite的簡單工作示例。只有兩個文件,燒瓶應用程序和編輯Jinja2 html模板。

使用的庫版本是Flask 0.10.1,Flask-SQLAlchemy 2.1和Flask-Admin 1.4。

根文件夾中的燒瓶應用flask-ckeditor.py

from flask import Flask 
from flask.ext.admin import Admin 
from flask.ext.admin.contrib.sqla import ModelView 
from flask.ext.admin.menu import MenuLink 
from flask.ext.sqlalchemy import SQLAlchemy 
from wtforms.widgets import TextArea, TextInput 
from wtforms.fields import TextAreaField 

app = Flask(__name__) 

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:' 
app.config['SQLALCHEMY_ECHO'] = True 
app.config['DEBUG'] = True 
app.config['SECRET_KEY'] = 'super-secret' 

db = SQLAlchemy(app) 


class Test(db.Model): 
    __tablename__ = 'tests' 
    id = db.Column(db.Integer, primary_key=True) 
    text = db.Column(db.UnicodeText) 


class CKEditorWidget(TextArea): 
    def __call__(self, field, **kwargs): 
     if kwargs.get('class'): 
      kwargs['class'] += " ckeditor" 
     else: 
      kwargs.setdefault('class', 'ckeditor') 
     return super(CKEditorWidget, self).__call__(field, **kwargs) 


class CKEditorField(TextAreaField): 
    widget = CKEditorWidget() 


class TestAdminView(ModelView): 
    form_overrides = dict(text=CKEditorField) 
    can_view_details = True 
    create_template = 'edit.html' 
    edit_template = 'edit.html' 


@app.route('/') 
def index(): 
    return '<a href="/admin/">Click me to get to Admin!</a>' 

# Create admin 
admin = Admin(app, name='Admin') 
admin.add_view(TestAdminView(model=Test, session=db.session, category='Tables', name='Test')) 
admin.add_link(MenuLink(name='Public Website', category='', url='/')) 


def build_db(): 

    tests = [ 
     { 
      'text': "<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut</p>" 
     }, 
     { 
      'text': "<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque<p>" 
     }, 
     { 
      'text': "<p>At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium</p>" 
     } 
    ] 

    db.drop_all() 
    db.create_all() 

    for test in tests: 
     test_db = Test(**test) 
     db.session.add(test_db) 
    db.session.commit() 


@app.before_first_request 
def create_user(): 
    build_db() 

if __name__ == '__main__': 
    app.run(debug=True) 

的Jinja2的HTML模板文件templates/edit.html

{% extends 'admin/model/edit.html' %} 

{% block tail %} 
    {{ super() }} 
    <script src="http://cdnjs.cloudflare.com/ajax/libs/ckeditor/4.0.1/ckeditor.js"></script> 
{% endblock %} 
+0

太棒了!有用。在清除數據庫並重新創建數據庫之前,似乎沒有與現有的管理視圖一起工作,但現在它似乎完美地工作了。非常感謝所有的耐心和幫助。 –

0

您可以使用Flask-CKEditor來簡化代碼。它提供了一個CKEditorField,這正是你所需要的。我們需要先安裝它:

$ pip install flask-ckeditor 
在你的代碼

然後:

from flask_ckeditor import CKEditorField 
... 

class TestAdminView(ModelView): 
    form_overrides = dict(text=CKEditorField) 
    can_view_details = True 
    create_template = 'edit.html' 
    edit_template = 'edit.html' 

在模板:

{% extends 'admin/model/edit.html' %} 

{% block tail %} 
    {{ super() }} 
    {{ ckeditor.load() }} 
{% endblock %}