Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
flask-admin
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Python-Dev
flask-admin
Commits
b82188f7
Commit
b82188f7
authored
Mar 26, 2012
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Unique field validator for SQLAlchemy forms.
Refactored code a bit.
parent
93d911c4
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
76 additions
and
29 deletions
+76
-29
fileadmin.py
flask_adminex/ext/fileadmin.py
+2
-2
sqlamodel.py
flask_adminex/ext/sqlamodel.py
+68
-25
form.py
flask_adminex/form.py
+5
-1
model.py
flask_adminex/model.py
+1
-1
No files found.
flask_adminex/ext/fileadmin.py
View file @
b82188f7
...
...
@@ -16,7 +16,7 @@ from flask.ext.adminex import form
from
flask.ext
import
wtf
class
NameForm
(
wtf
.
Form
):
class
NameForm
(
form
.
Base
Form
):
"""
Form with a filename input field.
...
...
@@ -31,7 +31,7 @@ class NameForm(wtf.Form):
raise
wtf
.
ValidationError
(
'Invalid directory name'
)
class
UploadForm
(
form
.
Admin
Form
):
class
UploadForm
(
form
.
Base
Form
):
"""
File upload form. Works with FileAdmin instance to check if it is allowed
to upload file with given extension.
...
...
flask_adminex/ext/sqlamodel.py
View file @
b82188f7
from
sqlalchemy.orm.attributes
import
InstrumentedAttribute
from
sqlalchemy.orm.exc
import
NoResultFound
from
sqlalchemy.sql.expression
import
desc
from
wtforms
import
fields
from
wtforms
import
ValidationError
,
fields
from
wtforms.ext.sqlalchemy.orm
import
model_form
,
converts
,
ModelConverter
from
wtforms.ext.sqlalchemy.fields
import
QuerySelectField
,
QuerySelectMultipleField
from
flask
import
flash
from
flask.ext.adminex.model
import
BaseModelView
from
flask.ext.adminex
import
form
from
flask.ext.adminex
import
model
,
form
class
Unique
(
object
):
"""Checks field value unicity against specified table field.
:param get_session:
A function that return a SQAlchemy Session.
:param model:
The model to check unicity against.
:param column:
The unique column.
:param message:
The error message.
"""
field_flags
=
(
'unique'
,
)
def
__init__
(
self
,
db_session
,
model
,
column
,
message
=
None
):
self
.
db_session
=
db_session
self
.
model
=
model
self
.
column
=
column
self
.
message
=
message
def
__call__
(
self
,
form
,
field
):
try
:
obj
=
(
self
.
db_session
.
query
(
self
.
model
)
.
filter
(
self
.
column
==
field
.
data
)
.
one
())
if
not
hasattr
(
form
,
'_obj'
)
or
not
form
.
_obj
==
obj
:
if
self
.
message
is
None
:
self
.
message
=
field
.
gettext
(
u'Already exists.'
)
raise
ValidationError
(
self
.
message
)
except
NoResultFound
:
pass
class
AdminModelConverter
(
ModelConverter
):
...
...
@@ -30,37 +63,39 @@ class AdminModelConverter(ModelConverter):
return
None
def
convert
(
self
,
model
,
mapper
,
prop
,
field_args
):
if
not
field_args
:
field_args
=
dict
()
kwargs
=
{
'validators'
:
[],
'filters'
:
[]
}
if
field_args
:
kwargs
.
update
(
field_args
)
if
hasattr
(
prop
,
'direction'
):
remote_model
=
prop
.
mapper
.
class_
local_column
=
prop
.
local_remote_pairs
[
0
][
0
]
kwargs
=
{
'validators'
:
[],
'filters'
:
[],
kwargs
.
update
({
'allow_blank'
:
local_column
.
nullable
,
'label'
:
self
.
_get_label
(
prop
.
key
,
field_args
),
'query_factory'
:
lambda
:
self
.
view
.
session
.
query
(
remote_model
),
'default'
:
None
}
if
field_args
:
kwargs
.
update
(
field_args
)
'label'
:
self
.
_get_label
(
prop
.
key
,
kwargs
),
'query_factory'
:
lambda
:
self
.
view
.
session
.
query
(
remote_model
)
})
if
prop
.
direction
.
name
==
'MANYTOONE'
:
return
QuerySelectField
(
widget
=
form
.
ChosenSelectWidget
(),
**
kwargs
)
return
QuerySelectField
(
widget
=
form
.
ChosenSelectWidget
(),
**
kwargs
)
elif
prop
.
direction
.
name
==
'ONETOMANY'
:
# Skip backrefs
if
not
local_column
.
foreign_keys
and
self
.
view
.
hide_backrefs
:
return
None
return
QuerySelectMultipleField
(
widget
=
form
.
ChosenSelectWidget
(
multiple
=
True
),
**
kwargs
)
return
QuerySelectMultipleField
(
widget
=
form
.
ChosenSelectWidget
(
multiple
=
True
),
**
kwargs
)
elif
prop
.
direction
.
name
==
'MANYTOMANY'
:
return
QuerySelectMultipleField
(
widget
=
form
.
ChosenSelectWidget
(
multiple
=
True
),
**
kwargs
)
return
QuerySelectMultipleField
(
widget
=
form
.
ChosenSelectWidget
(
multiple
=
True
),
**
kwargs
)
else
:
# Ignore pk/fk
if
hasattr
(
prop
,
'columns'
):
...
...
@@ -69,12 +104,19 @@ class AdminModelConverter(ModelConverter):
if
column
.
foreign_keys
or
column
.
primary_key
:
return
None
field_args
[
'label'
]
=
self
.
_get_label
(
prop
.
key
,
field_args
)
# If field is unique, validate it
if
column
.
unique
:
kwargs
[
'validators'
]
.
append
(
Unique
(
self
.
view
.
session
,
model
,
column
))
# Apply label
kwargs
[
'label'
]
=
self
.
_get_label
(
prop
.
key
,
kwargs
)
return
super
(
AdminModelConverter
,
self
)
.
convert
(
model
,
mapper
,
prop
,
field_
args
)
kw
args
)
@
converts
(
'Date'
)
def
convert_date
(
self
,
field_args
,
**
extra
):
...
...
@@ -91,7 +133,7 @@ class AdminModelConverter(ModelConverter):
return
form
.
TimeField
(
**
field_args
)
class
ModelView
(
BaseModelView
):
class
ModelView
(
model
.
BaseModelView
):
"""
SQLALchemy model view
...
...
@@ -166,7 +208,8 @@ class ModelView(BaseModelView):
# Sanity check
if
len
(
p
.
columns
)
>
1
:
raise
Exception
(
'Automatic form scaffolding is not supported'
+
' for multi-column properties (
%
s.
%
s)'
%
(
self
.
model
.
__name__
,
p
.
key
))
' for multi-column properties (
%
s.
%
s)'
%
(
self
.
model
.
__name__
,
p
.
key
))
column
=
p
.
columns
[
0
]
...
...
@@ -183,7 +226,7 @@ class ModelView(BaseModelView):
Create form from the model.
"""
return
model_form
(
self
.
model
,
form
.
Admin
Form
,
form
.
Base
Form
,
self
.
form_columns
,
field_args
=
self
.
form_args
,
converter
=
AdminModelConverter
(
self
))
...
...
flask_adminex/form.py
View file @
b82188f7
...
...
@@ -5,10 +5,14 @@ from flask.ext import wtf
from
wtforms
import
fields
,
widgets
class
Admin
Form
(
wtf
.
Form
):
class
Base
Form
(
wtf
.
Form
):
"""
Customized form class.
"""
def
__init__
(
self
,
formdata
=
None
,
obj
=
None
,
prefix
=
''
,
**
kwargs
):
super
(
BaseForm
,
self
)
.
__init__
(
formdata
,
obj
,
prefix
,
**
kwargs
)
self
.
_obj
=
obj
@
property
def
has_file_field
(
self
):
...
...
flask_adminex/model.py
View file @
b82188f7
...
...
@@ -227,7 +227,7 @@ class BaseModelView(BaseView):
def
scaffold_form
(
self
):
"""
Create `form.
AdminForm`
class from the model. Must be implemented in
Create `form.
BaseForm` inherited
class from the model. Must be implemented in
the child class.
"""
raise
NotImplemented
(
'Please implement scaffold_form method'
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment