Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: BinaryField's schema type should be string #505 #506

Merged
merged 6 commits into from
Sep 8, 2021

Conversation

jtamm-red
Copy link
Contributor

No description provided.

@codecov
Copy link

codecov bot commented Sep 7, 2021

Codecov Report

Merging #506 (c4daa0e) into master (1407059) will decrease coverage by 0.01%.
The diff coverage is 50.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #506      +/-   ##
==========================================
- Coverage   98.58%   98.56%   -0.02%     
==========================================
  Files          57       57              
  Lines        5710     5723      +13     
==========================================
+ Hits         5629     5641      +12     
- Misses         81       82       +1     
Impacted Files Coverage Δ
drf_spectacular/openapi.py 96.78% <50.00%> (-0.13%) ⬇️
tests/test_regressions.py 100.00% <0.00%> (ø)
drf_spectacular/generators.py 97.98% <0.00%> (+0.05%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1407059...c4daa0e. Read the comment docs.

@@ -435,6 +435,8 @@ def _map_model_field(self, model_field, direction):
elif hasattr(models, 'JSONField') and isinstance(model_field, models.JSONField):
# fix for DRF==3.11 with django>=3.1 as it is not yet represented in the field_mapping
return build_basic_type(OpenApiTypes.OBJECT)
elif hasattr(models, 'BinaryField') and isinstance(model_field, models.BinaryField):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BinaryField has existed since Django 1.6, so we don't need to check whether it exists.

Suggested change
elif hasattr(models, 'BinaryField') and isinstance(model_field, models.BinaryField):
elif isinstance(model_field, models.BinaryField):

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is safe. Not happened nothing. We do not want get error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is unnecessary. Django 1.5 has been end-of-life for years - long before this package existed.

The equivalent check for JSONField is required as that was added more recently in Django 3.1 and Django 2.2 is still supported.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well. I will fix.

@@ -435,6 +435,8 @@ def _map_model_field(self, model_field, direction):
elif hasattr(models, 'JSONField') and isinstance(model_field, models.JSONField):
# fix for DRF==3.11 with django>=3.1 as it is not yet represented in the field_mapping
return build_basic_type(OpenApiTypes.OBJECT)
elif hasattr(models, 'BinaryField') and isinstance(model_field, models.BinaryField):
return build_basic_type(OpenApiTypes.STR)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems wrong to me. BinaryField is documented as storing raw binary data. That implies that we should be using OpenApiTypes.BINARY:

OpenApiTypes.BINARY: {'type': 'string', 'format': 'binary'},

If this were Base64 encoded we should be using OpenApiTypes.BYTE:

OpenApiTypes.BYTE: {'type': 'string', 'format': 'byte'},

See the data types section for OpenAPI v3.0.3.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right! I fixed for OpenApiTypes.BYTE

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've misunderstood me - this should be using OpenApiTypes.BINARY as BinaryField doesn't store Base64 encoded data, it stores raw binary data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am confused. JSON format should be base64 type. I fixed for OpenApiTypes.BINARY.

Copy link
Owner

@tfranzel tfranzel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ngnpope thanks for chiming in. your statement about the version check was correct. however, the statement about the type was incorrect.

i had a look and checked what is actually happening. DRF has no dedicated serializer field for this. what happens is that DRF tranlates models.BinaryField to a generic serializers.ModelField, which is then serialized with the models value_to_string/to_python. These methods translate the binary data (in the db field) to and from base64. I experimentally verified this just now.

tl;dr: this is correct:

        elif isinstance(model_field, models.BinaryField):
            return build_basic_type(OpenApiTypes.BYTE)

@jtamm-red: that was an excellent catch! thank you. please update the PR and squash & force push to one commit for a clean history.

@tfranzel tfranzel merged commit 22a82a1 into tfranzel:master Sep 8, 2021
@ngnpope
Copy link
Contributor

ngnpope commented Sep 8, 2021

These methods translate the binary data (in the db field) to and from base64. I experimentally verified this just now.

Ah, unexpected, but then I've always avoided BinaryField. Thanks! Sorry @jtamm-red.

tfranzel added a commit that referenced this pull request Sep 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants