Last active
December 21, 2015 13:39
-
-
Save cldershem/6314633 to your computer and use it in GitHub Desktop.
Adding the model "Post" to my admin views makes someone quite angry. The repo with the rest of the code can be found at https://github.com/cldershem/homelessgaffer .
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from flask.ext.admin import (Admin, BaseView, AdminIndexView, expose) | |
from app import app, db | |
from flask.ext.admin.contrib.mongoengine import ModelView | |
from models import User, Post, Page | |
from utils import CKTextAreaField | |
class AdminView(BaseView): | |
@expose('/') | |
def index(self): | |
return self.render('index.html') | |
class UserView(ModelView): | |
column_filters = ['email'] | |
class PostView(ModelView): | |
column_filters = ['title'] | |
class PageView(ModelView): | |
column_filters = ['title'] | |
#form_overrides = dict(content=CKTextAreaField) | |
#create_template = 'admin/edit.html' | |
#edit_template = 'admin/edit.html' | |
admin = Admin(app) | |
admin.add_view(UserView(User)) | |
admin.add_view(PostView(Post)) | |
admin.add_view(PageView(Page)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from flask.ext.wtf import Form | |
from wtforms import ( TextField, TextAreaField, validators, PasswordField, | |
SubmitField, BooleanField, ValidationError ) | |
from wtforms.validators import Required, EqualTo | |
from models import db, User, Post, Comment, Page | |
from mongoengine.queryset import DoesNotExist | |
from utils import makeSlug, CKTextAreaField | |
class LoginForm(Form): | |
email = TextField('email', [validators.Required( | |
"Please enter a username.")]) | |
password = PasswordField('password', [validators.Required( | |
"Please enter a password")]) | |
remember_me = BooleanField('remember me') | |
submit = SubmitField("login") | |
def __init__(self, *args, **kwargs): | |
Form.__init__(self, *args, **kwargs) | |
def validate(self): | |
if not Form.validate(self): | |
return False | |
try: | |
user = User.objects.get(email = self.email.data.lower()) | |
except DoesNotExist: | |
self.email.errors.append("Invalid email address") | |
return False | |
if user and user.check_password(self.password.data): | |
return True | |
else: | |
self.password.errors.append("Invalid password") | |
return False | |
class RegisterUser(Form): | |
firstname = TextField("First name", [validators.Required( | |
"Please enter your first name.")]) | |
lastname = TextField("Last name", [validators.Required( | |
"Please enter your last name.")]) | |
email = TextField("Email", [validators.Required( | |
"Please enter your email address."), | |
validators.Email( | |
"Please engter a valid email address.")]) | |
password = PasswordField('New Password', [validators.Required(), | |
EqualTo('confirm', | |
message='Passwords must match')]) | |
confirm = PasswordField('Confirm', [validators.Required( | |
"Password again, please.")]) | |
submit = SubmitField("Create account") | |
def __init__(self, *args, **kwargs): | |
Form.__init__(self, *args, **kwargs) | |
def validate(self): | |
if not Form.validate(self): | |
return False | |
try: | |
user = User.objects.get(email=self.email.data.lower()) | |
self.email.errors.append("That email already exists.") | |
return False | |
except DoesNotExist: | |
return True | |
class PostForm(Form): | |
title = TextField("Title", [validators.Required( | |
"Please enter a title for your post.")]) | |
body = CKTextAreaField("Body", [validators.Required( | |
"Please enter a body to your post.")]) | |
tags = TextField("Tags") | |
submit = SubmitField("Create Post") | |
def __init__(self, *args, **kwargs): | |
Form.__init__(self, *args, **kwargs) | |
def validate(self): | |
if not Form.validate(self): | |
return False | |
try: | |
newSlug = makeSlug(self.title.data) | |
slug = Post.objects.get(slug=newSlug) | |
self.slug.errors.append("That title already exists.") | |
return False | |
except DoesNotExist: | |
return True | |
class CommentForm(Form): | |
comment = TextAreaField('comment', [validators.Required()]) | |
submit = SubmitField("submit") | |
class PageForm(Form): | |
title = TextField("Title", [validators.Required( | |
"Please enter a title for your page.")]) | |
content = CKTextAreaField("Content", [validators.Required( | |
"Please enter content for your page.")]) | |
submit = SubmitField("Submit Page") | |
def validate(self): | |
if not Form.validate(self): | |
return False | |
try: | |
slug = makeSlug(self.title.data) | |
page = Page.objects.get(slug=slug) | |
self.title.errors.append("That page already exists.") | |
return False | |
except DoesNotExist: | |
return True | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import datetime | |
from flask import url_for | |
from app import app, db | |
from werkzeug import generate_password_hash, check_password_hash | |
from utils import makeSlug | |
class User(db.Document): | |
class Roles(db.EmbeddedDocument): | |
can_login = db.BooleanField(required=True, default=True) | |
can_comment = db.BooleanField(required=True, default=True) | |
can_post = db.BooleanField(required=True, default=True) | |
is_admin = db.BooleanField(required=True, default=False) | |
created_at = db.DateTimeField(default=datetime.datetime.now, | |
required=True) | |
firstname = db.StringField(max_length=64) | |
lastname = db.StringField(max_length=100) | |
email = db.StringField(max_length=120, unique=True) | |
pwdhash = db.StringField(max_length=54) | |
roles = db.EmbeddedDocumentField(Roles, default=Roles) | |
def set_password(self, password): | |
self.pwdhash = generate_password_hash(password) | |
def check_password(self, password): | |
return check_password_hash(self.pwdhash, password) | |
def is_authenticated(self): | |
return True | |
def is_active(self): | |
return True | |
def is_anonymous(self): | |
return False | |
def get_id(self): | |
return self.email | |
def __repr__(self): | |
return '<User %r, %r>' % (self.firstname, self.email) | |
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) | |
author = db.ReferenceField(User) | |
body = db.StringField(required=True) | |
tags = db.ListField(db.StringField(max_length=50)) | |
comments = db.ListField(db.EmbeddedDocumentField('Comment')) | |
def get_absolute_url(self): | |
return url_for('post', kwargs={"slug": self.slug}) | |
def __unicode__(self): | |
return self.title | |
meta = { | |
'allow_inheritance': True, | |
'indexes': ['-created_at', 'slug'], | |
'ordering': ['-created_at'] | |
} | |
def __repr__(self): | |
return '<Post %r, -%r>' % (self.slug, self.author) | |
class Comment(db.EmbeddedDocument): | |
created_at = db.DateTimeField(default=datetime.datetime.now, | |
required=True) | |
body = db.StringField(required=True) | |
author = db.ReferenceField(User) | |
def __repr__(self): | |
return '<Post %r>' % (self.author) | |
class Page(db.Document): | |
created_at = db.DateTimeField(default=datetime.datetime.now, | |
required=True) | |
title = db.StringField(required=True) | |
slug = db.StringField(required=True) | |
content = db.StringField(required=True) | |
author = db.ReferenceField(User) | |
meta = { | |
'allow_inheritance': True, | |
'indexes': ['-created_at', 'title'], | |
'ordering': ['-created_at'] | |
} | |
def __repr__(self): | |
return '<Page %r>' % (self.title) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
./run.py | |
Traceback (most recent call last): | |
File "./run.py", line 2, in <module> | |
from app import app | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/app/__init__.py", line 15, in <module> | |
from app import routes, models, admin | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/app/admin.py", line 28, in <module> | |
admin.add_view(PostView(Post)) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/contrib/mongoengine/view.py", line 105, in __init__ | |
super(ModelView, self).__init__(model, name, category, endpoint, url) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/model/base.py", line 371, in __init__ | |
self._refresh_cache() | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/model/base.py", line 387, in _refresh_cache | |
self._create_form_class = self.get_create_form() | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/model/base.py", line 594, in get_create_form | |
return self.get_form() | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/model/base.py", line 586, in get_form | |
return self.scaffold_form() | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/contrib/mongoengine/view.py", line 240, in scaffold_form | |
converter=self.model_form_converter()) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/contrib/mongoengine/form.py", line 63, in model_form | |
converter=converter) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_mongoengine/wtf/orm.py", line 268, in model_form | |
field_dict = model_fields(model, only, exclude, field_args, converter) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_mongoengine/wtf/orm.py", line 236, in model_fields | |
field = converter.convert(model, model_field, field_args.get(name)) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_mongoengine/wtf/orm.py", line 78, in convert | |
return self.converters[ftype](model, field, kwargs) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/contrib/mongoengine/form.py", line 35, in conv_List | |
unbound_field = self.convert(model, field.field, {}) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_mongoengine/wtf/orm.py", line 78, in convert | |
return self.converters[ftype](model, field, kwargs) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/contrib/mongoengine/form.py", line 50, in conv_EmbeddedDocument | |
form_class = model_form(field.document_type_obj, field_args={}) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_admin/contrib/mongoengine/form.py", line 63, in model_form | |
converter=converter) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_mongoengine/wtf/orm.py", line 268, in model_form | |
field_dict = model_fields(model, only, exclude, field_args, converter) | |
File "/home/cldershem/Documents/Development/homelessgaffer.com/hg-Python/venv/local/lib/python2.7/site-packages/flask_mongoengine/wtf/orm.py", line 220, in model_fields | |
raise TypeError('model must be a mongoengine Document schema') | |
TypeError: model must be a mongoengine Document schema |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment