Skip to content

Commit

Permalink
Merge pull request #38 from Martlark/1.5.2
Browse files Browse the repository at this point in the history
1.5.2 release
  • Loading branch information
Martlark authored Jun 26, 2021
2 parents e47d3c2 + cb2b2a1 commit 2fbd217
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 13 deletions.
31 changes: 23 additions & 8 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ Using `get_delete_put_post`.

As example: add a `Stat` object to a Survey object using the `get_delete_put_post` convenience method. The foreign key
to the parent `Survey` is provided in the form data as survey_id. `create_fields` list must then include `survey_id` as
the foreign key field to be set.
the foreign key field to be set if you specify any `create_fields`. By default all fields are allowed to be included
when creating.

.. code:: html

Expand All @@ -269,7 +270,7 @@ the foreign key field to be set.
Writing and creating
====================

When using any of the convenience methods to update, create or delete an object. These properties and
When using any of the convenience methods to update, create or delete an object these properties and
methods control how flask-serialize handles the operation.

Updating from a form or json
Expand Down Expand Up @@ -389,6 +390,8 @@ Private fields
Fields can be made private for certain reasons by overriding the `fs_private_field` method
and returning `True` if the field is to be private.

Private fields will be excluded for any get, put and post methods.

Example:

To exclude private fields when a user is not the admin.
Expand Down Expand Up @@ -510,7 +513,7 @@ List of model field names to not serialize at all.
exclude_serialize_fields = []
List of model field names to not serialize when return as json.
List of model field names to not serialize when returning as json.

.. code:: python
Expand All @@ -519,14 +522,14 @@ List of model field names to not serialize when return as json.
Filtering json list results
---------------------------

Json result lists can be filtered by using the `prop_filters` on either
Json result lists can be filtered by using the `prop_filters` parameter on either
the `get_delete_put_post` method or the `json_list` method.

The filter consists of one or more properties in the json result and
the value that it must match. Filter items will match against the
first prop_filter property to exactly equal the value.
first `prop_filter` property to exactly equal the value.

NOTE: The filter is not applied with PUT, single GET or DELETE.
NOTE: The filter is not applied with single a GET or, the PUT, POST and DELETE methods.

Example to only return dogs:

Expand Down Expand Up @@ -660,6 +663,8 @@ Notes:
* To add or modify values from a Flask request object before they are applied to the instance use the ``before_update`` hook.
``verify`` is called after ``before_update``.

* To undertake actions after a commit use ``fs_after_commit`` hook.


Mixin Helper methods and properties
===================================
Expand Down Expand Up @@ -722,6 +727,16 @@ as_json
:return: json object
"""
fs_after_commit(self, create=False)
-----------------------------------

.. code:: python
def fs_after_commit(self, create=False):
Hook to call after any `update_from_dict`, `request_update_form`, `request_update_json` has been called so that
you do what you like. `self` is the updated or created (create==True) item.

before_update(cls, data_dict)
-----------------------------

Expand Down Expand Up @@ -981,6 +996,7 @@ Example to create using POST:
Release Notes
-------------

* 1.5.2 - Test with flask 2.0. Add fs_after_commit method to allow post create/update actions. Improve documentation.
* 1.5.1 - Fix TypeError: unsupported operand type(s) for +=: 'ImmutableColumnCollection' and 'list' with newer versions of SQLAlchemy
* 1.5.0 - Return item from POST/PUT updates. Allow create_fields and update_fields to be specified using the column fields. None values serialize as null/None. Restore previous update_properties behaviour. By default updates/creates using all fields. Exclude primary key from create and update.
* 1.4.2 - by default return all props with update_properties
Expand Down Expand Up @@ -1009,5 +1025,4 @@ Licensing
- Apache 2.0

.. |PyPI Version| image:: https://img.shields.io/pypi/v/flask-serialize.svg
:target: https://pypi.python.org/pypi/flask-serialize

:target: https://pypi.python.org/pypi/flask-serialize
13 changes: 12 additions & 1 deletion flask_serialize/flask_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class FlaskSerializeMixin:
# previous values of an instance before update attempted
previous_field_value = {}
# current version
__version__ = '1.5.1'
__version__ = '1.5.2'

def before_update(self, data_dict):
"""
Expand All @@ -56,6 +56,14 @@ def before_update(self, data_dict):
"""
return data_dict

def fs_after_commit(self, create=False):
"""
hook to call after any put/post commit so that you may do something
self will be the new / updated committed item
:param create: True when item was just created.
"""

def to_date_short(self, d):
"""
convert the given date field to a short date / time without fractional seconds
Expand Down Expand Up @@ -474,6 +482,7 @@ def request_create_form(cls, **kwargs):
new_item.update_timestamp()
cls.db.session.add(new_item)
cls.db.session.commit()
new_item.fs_after_commit(create=True)
return new_item

def request_update_form(self):
Expand All @@ -496,6 +505,7 @@ def request_update_form(self):
raise Exception('FlaskSerializeMixin property "db" is not set')
self.db.session.add(self)
self.db.session.commit()
self.fs_after_commit(self)
return True

def request_update_json(self):
Expand Down Expand Up @@ -523,6 +533,7 @@ def request_update_json(self):
raise Exception('FlaskSerializeMixin property "db" is not set')
self.db.session.add(self)
self.db.session.commit()
self.fs_after_commit()
return True

def update_timestamp(self):
Expand Down
4 changes: 2 additions & 2 deletions pypar.commands.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ pip install pytest-flask

. venv3/bin/activate
python setup.py sdist bdist_wheel
twine check dist/flask_serialize-1.5.1*
twine upload dist/flask_serialize-1.5.1* -u martlark
twine check dist/flask_serialize-1.5.2*
twine upload dist/flask_serialize-1.5.2* -u martlark
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from codecs import open
from setuptools import setup

VERSION = '1.5.1'
VERSION = '1.5.2'
LONG_DESCRIPTION = open('README.rst', 'r', encoding='utf-8').read()

setup(
Expand Down
8 changes: 8 additions & 0 deletions test/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import string
import time
from datetime import datetime
from pathlib import Path

import pytest
from flask import g

from test.test_flask_app import app, db, Setting, SubSetting, SimpleModel, DateTest

Expand Down Expand Up @@ -444,6 +446,8 @@ def test_create_update_json(client):
json=dict(setting_type='test', key=key, value=value, number=10,
scheduled=dt_now.strftime(Setting.scheduled_date_format)))
assert rv.status_code == 200, rv.data
after_commit = Path('after_commit.tmp').read_text()
assert after_commit == f"""fs_after_commit: {False} {item.id}"""
item = Setting.query.filter_by(key=key).first()
assert item
assert item.value == value
Expand All @@ -457,6 +461,8 @@ def test_create_update_delete(client):
rv = client.post('/setting_add', data=dict(setting_type='test', key=key, value=value, number=10))
assert rv.status_code == 302, rv.data
item = Setting.query.filter_by(key=key).first()
after_commit = Path('after_commit.tmp').read_text()
assert after_commit.startswith(f"""fs_after_commit: {True} {item.id}""")
assert item
assert item.value == value
# test that number is not set on creation as it is not included in create_fields
Expand Down Expand Up @@ -504,6 +510,8 @@ def test_form_page(client):
rv = client.post('/setting_form_add', data=dict(setting_type='test', key=key, value='test-value', number=10))
assert rv.status_code == 302
item = Setting.query.filter_by(key=key).first()
after_commit = Path('after_commit.tmp').read_text()
assert after_commit.startswith(f"""fs_after_commit: {True} {item.id}""")
assert item
assert item.value == 'test-value'
# test that number is not set on creation as it is not included in create_fields
Expand Down
6 changes: 5 additions & 1 deletion test/test_flask_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import time
from datetime import datetime, timedelta

from flask import Flask, redirect, url_for, Response, request, render_template, flash
from flask import Flask, redirect, url_for, Response, request, render_template, flash, g
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
Expand Down Expand Up @@ -309,6 +309,10 @@ def before_update(self, data_dict):
d['active'] = d.get('active', 'n')
return d

def fs_after_commit(self, create=False):
with open('after_commit.tmp', 'w') as f:
f.write(f"""fs_after_commit: {create} {self.id}""")

# checks if Flask-Serialize can access
def can_access(self):
if self.value == '123456789':
Expand Down

0 comments on commit 2fbd217

Please sign in to comment.