Skip to content

Commit

Permalink
Merge pull request #5 from grahamu/all-purpose-validate
Browse files Browse the repository at this point in the history
Refactoring validate() to handle resource data collections
  • Loading branch information
brosner committed May 13, 2016
2 parents 9890156 + d1339c1 commit 8a1a7ce
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
32 changes: 26 additions & 6 deletions pinax/api/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,22 +123,42 @@ def parse_data(self):
raise ErrorResponse(**self.error_response_kwargs(str(e), title="Invalid JSON", status=400))

@contextlib.contextmanager
def validate(self, resource_class, obj=None):
def validate(self, resource_class, collection=False, obj=None):
"""
Generator yields either a validated resource (collection=False)
or a resource generator callable (collection=True).
ValidationError exceptions resulting from subsequent (after yield)
resource manipulation cause an immediate ErrorResponse.
"""
data = self.parse_data()
if "data" not in data:
raise ErrorResponse(**self.error_response_kwargs('Missing "data" key in payload.', status=400))
if "attributes" not in data["data"]:
raise ErrorResponse(**self.error_response_kwargs('Missing "attributes" key in data.', status=400))
resource = resource_class()

if collection and not isinstance(data["data"], list):
raise ErrorResponse(**self.error_response_kwargs("Data must be in a list.", status=400))

try:
resource.populate(data["data"], obj=obj)
yield resource
if collection:
yield (self.validate_resource(resource_class, resource_data, obj) for resource_data in data["data"])
else:
yield self.validate_resource(resource_class, data["data"], obj)
except ValidationError as exc:
raise ErrorResponse(
TopLevel.from_validation_error(exc, resource_class).serializable(),
status=400,
)

def validate_resource(self, resource_class, resource_data, obj=None):
"""
Validates resource data for a resource class.
"""
if "attributes" not in resource_data:
raise ErrorResponse(**self.error_response_kwargs('Missing "attributes" key in data.', status=400))
resource = resource_class()
resource.populate(resource_data, obj=obj)
return resource

def render(self, resource, **kwargs):
try:
payload = self.create_top_level(resource, **kwargs).serializable(request=self.request)
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[flake8]
ignore = E265,E501
max-line-length = 100
max-complexity = 10
max-complexity = 12
exclude = migrations/*,docs/*

[tox]
Expand Down

0 comments on commit 8a1a7ce

Please sign in to comment.