Skip to content

Commit

Permalink
Merge pull request #48 from Martlark/2.1.2
Browse files Browse the repository at this point in the history
2.1.2 fix formatting issues with readme
  • Loading branch information
Martlark authored Nov 30, 2022
2 parents 6d5ff12 + 47d4d04 commit b275e12
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 117 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10"]
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
Expand Down
46 changes: 20 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ from the db and easy to use write back of models using PUT and POST.
```python
# example database model
from flask_serialize import FlaskSerialize
from datetime import datetime

# required to set class var db for writing to a database
from app import db
Expand Down Expand Up @@ -642,20 +643,14 @@ Put, get, delete, post and get-all magic method handler.
- `user`: user to user as query filter.
- `prop_filters`: dictionary of key:value pairs to limit results when returning get-all.

====== ================================================================================================== ============================
Method Operation Response
====== ================================================================================================== ============================
GET returns one item when `item_id` is a primary key. {property1:value1,property2:value2,...}
GET returns all items when `item_id` is None. \[{item1},{item2},...\]
PUT updates item using `item_id` as the id from request json data. Calls the model `__fs_verify__` {message:message,item:{model_fields,...},properties:{`__fs_update_properties__`}}
before updating. Returns new item as {item}
DELETE removes the item with primary key of `item_id` if self.__fs_can_delete__ does not throw an error. {property1:value1,property2:value2,...}
Returns the item removed. Calls `__fs_can_delete__` before delete.
POST creates and returns a Flask response with a new item as json from form body data or JSON body data {property1:value1,property2:value2,...}
when `item_id` is None. Calls the model `__fs_verify__` method before creating.
POST updates an item from form data using `item_id`. {message:message,item:{model_fields,...},properties:{`__fs_update_properties__`}}
Calls the model ` __fs_verify__` method before updating.
====== ================================================================================================== ============================
| Method Operation | item_id | Response |
|------------------|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| GET | primary key | returns one item when `item_id` is a primary key. {property1:value1,property2:value2,...} |
| GET | None | returns all items when `item_id` is None. [{item1},{item2},...] |
| PUT | primary key | updates item using `item_id` as the id from request json data. Calls the model `__fs_verify__` `{message:message,item:{model_fields,...}`, properties:{`__fs_update_properties__`}} before updating. Returns new item as {item} |
| DELETE | primary key | removes the item with primary key of `item_id` if self.__fs_can_delete__ does not throw an error. `{property1:value1,property2:value2,...}` Returns the item removed. Calls `__fs_can_delete__` before delete. |
| POST | None | creates and returns a Flask response with a new item as json from form body data or JSON body data {property1:value1,property2:value2,...} When `item_id` is None. Calls the model `__fs_verify__` method before creating. |
| POST | primary key | updates an item from form data using `item_id`. Calls the model ` __fs_verify__` method before updating. |

On error returns a response of 'error message' with http status code of 400.

Expand Down Expand Up @@ -851,18 +846,16 @@ Prerequisites.

Setup the class properties to use your form items.

============================= =============================================================================================================================
Property Usage
============================= =============================================================================================================================
form_page_form **Required**. WTForm Class name
form_page_route_create **Required**. Name of the method to redirect after create, uses: url_for(cls.form_route_create, item_id=id)
form_page_route_update **Required**. Name of the method to redirect after updating, uses: url_for(cls.form_route_update, item_id=id)
form_page_template **Required**. Location of the template file to allow edit/add
form_page_update_format Format string to format flash message after update. `item` (the model instance) is passed as the only parameter. Set to '' or None to suppress flash.
form_page_create_format Format string to format flash message after create. `item` (the model instance) is passed as the only parameter. Set to '' or None to suppress flash.
form_page_update_title_format Format string to format title template value when editing. `item` (the model instance) is passed as the only parameter.
form_page_create_title_format Format string to format title template value when creating. `cls` (the model class) is passed as the only parameter.
============================= =============================================================================================================================
| Property | Usage |
|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
| form_page_form | **Required**. WTForm Class name |
| form_page_route_create | **Required**. Name of the method to redirect after create, uses: url_for(cls.form_route_create, item_id=id) |
| form_page_route_update | **Required**. Name of the method to redirect after updating, uses: url_for(cls.form_route_update, item_id=id) |
| form_page_template | **Required**. Location of the template file to allow edit/add |
| form_page_update_format | Format string to format flash message after update. `item` (the model instance) is passed as the only parameter. Set to '' or None to suppress flash. |
| form_page_create_format | Format string to format flash message after create. `item` (the model instance) is passed as the only parameter. Set to '' or None to suppress flash. |
| form_page_update_title_format | Format string to format title template value when editing. `item` (the model instance) is passed as the only parameter. |
| form_page_create_title_format | Format string to format title template value when creating. `cls` (the model class) is passed as the only parameter. |

The routes must use item_id as the parameter for editing. Use no parameter when creating.

Expand Down Expand Up @@ -937,6 +930,7 @@ Version 2.0.1 changes most of the properties, hooks and methods to use a more no

## Release Notes

- 2.1.2 - Fix readme table format
- 2.1.1 - Improve sqlite JSON handling
- 2.1.0 - Convert readme to markdown. Add support for JSON columns. Withdraw Python 3.6 Support. Use unittest instead of pytest. NOTE: Changes `__fs_convert_types__` to a `dict`.
- 2.0.3 - Allow more use of model column variables instead of "quoted" field names. Fix missing import for FlaskSerialize.
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.1
2.1.2
24 changes: 12 additions & 12 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
wtforms>=3.0.1
flask>=2.2.1
SQLAlchemy>=1.4.39
Permissive-Dict>=1.0.4
flask-sqlalchemy>=2.5.1
flask-wtf>=1.0.1
setuptools>=63.4.2
wheel>=0.37.1
twine>=4.0.1
black>=22.6.0
flask-unittest
flask-migrate>=3.1.0
wtforms==3.0.1
flask==2.2.2
SQLAlchemy==1.4.44
Permissive-Dict==1.0.4
flask-sqlalchemy==3.0.2
flask-wtf==1.0.1
setuptools==65.6.3
wheel==0.38.4
twine==4.0.1
black==22.10.0
flask-unittest==0.1.3
flask-migrate==4.0.0
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Operating System :: POSIX",
"Operating System :: MacOS",
"Operating System :: Unix",
Expand Down
159 changes: 82 additions & 77 deletions test/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ def setUp(self, app, client) -> None:
:return:
"""
with app.app_context():
db.drop_all(app=app)
db.create_all(app=app)
db.drop_all()
db.create_all()

def create_app(self):
app.config["TESTING"] = True
Expand All @@ -49,7 +49,6 @@ def create_app(self):
yield app

def tearDown(self, app, client):
db.drop_all(app=app)
db.session.execute(text("drop table if exists test_table"))
db.session.remove()

Expand Down Expand Up @@ -711,28 +710,29 @@ def test_default__fs_create_fields__(self, app, client):
def test_simple_model__fs_update_fields__(self, app, client):
value = random_string()
# add
item = SimpleModel(value=value)
db.session.add(item)
db.session.commit()
item = SimpleModel.query.filter_by(value=value).first_or_404()
# form
value = random_string()
prop = random_string()
rv = client.post(
"/simple_edit/{}".format(item.id), data=dict(value=value, prop=prop)
)
assert 200 == rv.status_code, rv.data
assert rv.json["item"]["value"] == value, rv.data
assert b"Updated" in rv.data, rv.data
# json
value = random_string()
rv = client.put(
"/simple_edit/{}".format(item.id), json=dict(value=value, id="dskdsf")
)
assert 200 == rv.status_code, rv.data
assert rv.json["item"]["value"] == value, rv.data
assert rv.json["item"]["prop"] == "prop:" + value, rv.data
assert b"Updated" in rv.data, rv.data
with app.app_context():
item = SimpleModel(value=value)
db.session.add(item)
db.session.commit()
item = SimpleModel.query.filter_by(value=value).first_or_404()
# form
value = random_string()
prop = random_string()
rv = client.post(
"/simple_edit/{}".format(item.id), data=dict(value=value, prop=prop)
)
assert 200 == rv.status_code, rv.data
assert rv.json["item"]["value"] == value, rv.data
assert b"Updated" in rv.data, rv.data
# json
value = random_string()
rv = client.put(
"/simple_edit/{}".format(item.id), json=dict(value=value, id="dskdsf")
)
assert 200 == rv.status_code, rv.data
assert rv.json["item"]["value"] == value, rv.data
assert rv.json["item"]["prop"] == "prop:" + value, rv.data
assert b"Updated" in rv.data, rv.data

def test_override_datetime_conversion(self, app, client):
key = random_string()
Expand All @@ -754,64 +754,69 @@ def test_fs_json_get(self, app, client):
setting_type = random_string()
# test add setting
Setting.__model_props = {}
item = Setting(setting_type=setting_type, key=key, value=test_value)
db.session.add(item)
db.session.commit()
item = Setting.query.get_or_404(item.id)
# get by id
rv = client.get("/setting_get_json/{}".format(item.id))
assert rv.json["value"] == test_value
assert rv.json["key"] == key
assert rv.json["setting_type"] == setting_type
rv = client.get("/setting_get_json/{}".format(item.id + 100))
assert rv.status_code == 200
assert rv.json == {}
# get first
rv = client.get("/setting_fs_json_first/{}".format(item.key))
assert rv.json["value"] == test_value
assert rv.json["key"] == key
assert rv.json["setting_type"] == setting_type
assert (
client.get("/setting_fs_json_first/{}".format(random_string())).json == {}
)
with app.app_context():
item = Setting(setting_type=setting_type, key=key, value=test_value)
db.session.add(item)
db.session.commit()
item = Setting.query.get_or_404(item.id)
# get by id
rv = client.get("/setting_get_json/{}".format(item.id))
assert rv.json["value"] == test_value
assert rv.json["key"] == key
assert rv.json["setting_type"] == setting_type
rv = client.get("/setting_get_json/{}".format(item.id + 100))
assert rv.status_code == 200
assert rv.json == {}
# get first
rv = client.get("/setting_fs_json_first/{}".format(item.key))
assert rv.json["value"] == test_value
assert rv.json["key"] == key
assert rv.json["setting_type"] == setting_type
assert (
client.get("/setting_fs_json_first/{}".format(random_string())).json
== {}
)

def test_get_0_is_not_null(self, app, client):
key = random_string()
item = Setting(id=0, setting_type="hello", value=random_string(), key=key)
db.session.add(item)
db.session.commit()
# should get a list
rv = client.get("/setting_get_all")
assert rv.status_code == 200
assert len(rv.json) == 1
assert rv.json[0]["key"] == key
# should get one item not a list
rv = client.get("/setting_get/0")
assert rv.status_code == 200
assert rv.json["key"] == key
with app.app_context():
item = Setting(id=0, setting_type="hello", value=random_string(), key=key)
db.session.add(item)
db.session.commit()
# should get a list
rv = client.get("/setting_get_all")
assert rv.status_code == 200
assert len(rv.json) == 1
assert rv.json[0]["key"] == key
# should get one item not a list
rv = client.get("/setting_get/0")
assert rv.status_code == 200
assert rv.json["key"] == key

def test_timestamp_is_updated_and_can_be_overridden(self, app, client):
key = random_string()
item = Setting(setting_type="hello", value=random_string(), key=key)
db.session.add(item)
db.session.commit()
new_value = random_string()
item = Setting.query.get_or_404(item.id)
sub_item = item.add_sub(new_value)
sub_item_id = sub_item.id
updated_when_created = sub_item.sub_updated
# update using put
new_value = random_string()
assert (
200
== client.put(
"/sub_setting_put/{}".format(sub_item_id), json=dict(flong=new_value)
).status_code
)
updated_item = SubSetting.query.get_or_404(sub_item_id)
assert updated_item.flong == new_value
# test custom update works and that __fs_timestamp_fields__ works
assert updated_when_created > updated_item.sub_updated
with app.app_context():
item = Setting(setting_type="hello", value=random_string(), key=key)
db.session.add(item)
db.session.commit()
new_value = random_string()
item = Setting.query.get_or_404(item.id)
sub_item = item.add_sub(new_value)
sub_item_id = sub_item.id
updated_when_created = sub_item.sub_updated
# update using put
new_value = random_string()
assert (
200
== client.put(
"/sub_setting_put/{}".format(sub_item_id),
json=dict(flong=new_value),
).status_code
)
updated_item = SubSetting.query.get_or_404(sub_item_id)
assert updated_item.flong == new_value
# test custom update works and that __fs_timestamp_fields__ works
assert updated_when_created > updated_item.sub_updated

def test_user(self, app, client):
test_value = random_string()
Expand Down

0 comments on commit b275e12

Please sign in to comment.