Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite4ce07f

Browse files
carltongibsonPierre Chiquet
authored and
Pierre Chiquet
committed
Extract method formanual_fields processing (encode#5633)
* Extract method for `manual_fields` processingAllows reuse of logic to replace Field instances in a field list by `Field.name`.Adds a utility function for the logic plus a wrapper method on `AutoSchema`.Closesencode#5632* Manual fields suggestions (encode#2)* Use OrderedDict in inspectors* Move empty check to 'update_fields()'* Make 'update_fields()' an AutoSchema staticmethod* Add 'AutoSchema.get_manual_fields()'* Conform '.get_manual_fields()' to other methods* Add test for update_fields* Make sure `manual_fields` is a list.(As documented to be)* Add docs for new AutoSchema methods.* `get_manual_fields`* `update_fields`* Add release notes for PR.
1 parent3a96e58 commite4ce07f

File tree

4 files changed

+111
-8
lines changed

4 files changed

+111
-8
lines changed

‎docs/api-guide/schemas.md‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,31 @@ Return a list of `coreapi.Link()` instances, as returned by the `get_schema_fiel
603603

604604
Return a list of`coreapi.Link()` instances, as returned by the`get_schema_fields()` method of any filter classes used by the view.
605605

606+
###get_manual_fields(self, path, method)
607+
608+
Return a list of`coreapi.Field()` instances to be added to or replace generated fields. Defaults to (optional)`manual_fields` passed to`AutoSchema` constructor.
609+
610+
May be overridden to customise manual fields by`path` or`method`. For example, a per-method adjustment may look like this:
611+
612+
```python
613+
defget_manual_fields(self,path,method):
614+
"""Example adding per-method fields."""
615+
616+
extra_fields= []
617+
if method=='GET':
618+
extra_fields=# ... list of extra fields for GET ...
619+
if method=='POST':
620+
extra_fields=# ... list of extra fields for POST ...
621+
622+
manual_fields=super().get_manual_fields()
623+
return manual_fields+ extra_fields
624+
```
625+
626+
###update_fields(fields, update_with)
627+
628+
Utility`staticmethod`. Encapsulates logic to add or replace fields from a list
629+
by`Field.name`. May be overridden to adjust replacement criteria.
630+
606631

607632
##ManualSchema
608633

‎docs/topics/release-notes.md‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ You can determine your currently installed version using `pip freeze`:
4040

4141
##3.7.x series
4242

43+
###3.7.4
44+
45+
**Date**: UNRELEASED
46+
47+
* Extract method for`manual_fields` processing[#5633][gh5633]
48+
49+
Allows for easier customisation of`manual_fields` processing, for example
50+
to provide per-method manual fields.`AutoSchema` adds`get_manual_fields`,
51+
as the intended override point, and a utility method`update_fields`, to
52+
handle by-name field replacement from a list, which, in general, you are not
53+
expected to override.
54+
55+
Note:`AutoSchema.__init__` now ensures`manual_fields` is a list.
56+
Previously may have been stored internally as`None`.
57+
58+
59+
[gh5633]:https://github.com/encode/django-rest-framework/issues/5633
60+
61+
4362

4463
###3.7.3
4564

‎rest_framework/schemas/inspectors.py‎

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,8 @@ def __init__(self, manual_fields=None):
172172
* `manual_fields`: list of `coreapi.Field` instances that
173173
will be added to auto-generated fields, overwriting on `Field.name`
174174
"""
175-
175+
ifmanual_fieldsisNone:
176+
manual_fields= []
176177
self._manual_fields=manual_fields
177178

178179
defget_link(self,path,method,base_url):
@@ -181,11 +182,8 @@ def get_link(self, path, method, base_url):
181182
fields+=self.get_pagination_fields(path,method)
182183
fields+=self.get_filter_fields(path,method)
183184

184-
ifself._manual_fieldsisnotNone:
185-
by_name= {f.name:fforfinfields}
186-
forfinself._manual_fields:
187-
by_name[f.name]=f
188-
fields=list(by_name.values())
185+
manual_fields=self.get_manual_fields(path,method)
186+
fields=self.update_fields(fields,manual_fields)
189187

190188
iffieldsandany([field.locationin ('form','body')forfieldinfields]):
191189
encoding=self.get_encoding(path,method)
@@ -379,6 +377,31 @@ def get_filter_fields(self, path, method):
379377
fields+=filter_backend().get_schema_fields(self.view)
380378
returnfields
381379

380+
defget_manual_fields(self,path,method):
381+
returnself._manual_fields
382+
383+
@staticmethod
384+
defupdate_fields(fields,update_with):
385+
"""
386+
Update list of coreapi.Field instances, overwriting on `Field.name`.
387+
388+
Utility function to handle replacing coreapi.Field fields
389+
from a list by name. Used to handle `manual_fields`.
390+
391+
Parameters:
392+
393+
* `fields`: list of `coreapi.Field` instances to update
394+
* `update_with: list of `coreapi.Field` instances to add or replace.
395+
"""
396+
ifnotupdate_with:
397+
returnfields
398+
399+
by_name=OrderedDict((f.name,f)forfinfields)
400+
forfinupdate_with:
401+
by_name[f.name]=f
402+
fields=list(by_name.values())
403+
returnfields
404+
382405
defget_encoding(self,path,method):
383406
"""
384407
Return the 'encoding' parameter to use for a given endpoint.

‎tests/test_schemas.py‎

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ def test_4605_regression(self):
516516
assertprefix=='/'
517517

518518

519-
classTestDescriptor(TestCase):
519+
classTestAutoSchema(TestCase):
520520

521521
deftest_apiview_schema_descriptor(self):
522522
view=APIView()
@@ -528,7 +528,43 @@ def test_get_link_requires_instance(self):
528528
withpytest.raises(AssertionError):
529529
descriptor.get_link(None,None,None)# ???: Do the dummy arguments require a tighter assert?
530530

531-
deftest_manual_fields(self):
531+
deftest_update_fields(self):
532+
"""
533+
That updating fields by-name helper is correct
534+
535+
Recall: `update_fields(fields, update_with)`
536+
"""
537+
schema=AutoSchema()
538+
fields= []
539+
540+
# Adds a field...
541+
fields=schema.update_fields(fields, [
542+
coreapi.Field(
543+
"my_field",
544+
required=True,
545+
location="path",
546+
schema=coreschema.String()
547+
),
548+
])
549+
550+
assertlen(fields)==1
551+
assertfields[0].name=="my_field"
552+
553+
# Replaces a field...
554+
fields=schema.update_fields(fields, [
555+
coreapi.Field(
556+
"my_field",
557+
required=False,
558+
location="path",
559+
schema=coreschema.String()
560+
),
561+
])
562+
563+
assertlen(fields)==1
564+
assertfields[0].requiredisFalse
565+
566+
deftest_get_manual_fields(self):
567+
"""That get_manual_fields is applied during get_link"""
532568

533569
classCustomView(APIView):
534570
schema=AutoSchema(manual_fields=[

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp