django-adapters icon indicating copy to clipboard operation
django-adapters copied to clipboard

Public API documentation

Open jpic opened this issue 6 years ago • 11 comments

This is second level API with features:

  • adapter schema & data validation,
  • adapter chaining,
  • nested adapters,
  • schema mutations,

Thanks in advance for your feedback

jpic avatar Mar 07 '18 14:03 jpic

Another bit of functionality that might be useful is merging two adapters. For example:

quick_registration_adapter = Adapter()
quick_registration_adapter.field_add(adapters.fields.Email('email'))

user_profile_adapter = Adapter()
user_profile_adapter.field_add(adapters.fields.String('name'))

full_registration_adapter = quick_registration_adapter.merge(user_profile_adapter)

LilyFoote avatar Mar 07 '18 17:03 LilyFoote

I think it would be helpful too to be able to select a subset of an existing adapter:

profile_adapter = Adapter()
profile_adapter.field_add(adapters.fields.String('name'))
profile_adapter.field_add(adapters.fields.Email('email', required=False))

registration_adapter = profile_adapter.select_fields(['email'])

LilyFoote avatar Mar 07 '18 17:03 LilyFoote

Batavia? ? https://github.com/pybee/batavia :confused:

luzfcb avatar Mar 07 '18 17:03 luzfcb

@luzfcb the idea of the batavia example is: if you have batavia script loaded it will be able to interpret the bytecode of a callback, otherwise it will be executed server side only. But most of the time we'll be using ~~validator~~ classes which will be picked up by a js class which is registered for the cls argument (python ValueEqual is continued on the client with js ValueEqual), in which case you still have a certain isomorphism to enhance your UI without loading a Python VM ;)

Thanks @Ian-Foote, with the distinction between validation and sanitization, we can have mutations without having an extra api. It seems features may be both used as a validator or a sanitizer or both such as LowerCase adapter, and that everything is an adapter, and all we have to do is finding what we want adapt() to do, as i will try to demonstrate.

jpic avatar Mar 07 '18 23:03 jpic

I understand your last comment is a big brain dump so I'll wait for you to clean it up in a new draft before digging into most of it. One thing I did want to pick up on immediately though is that I don't like a distinction between validators and adapters as separate parameters as you showed in this example:

assert StringAdapter(validators=[LowerCaseStringAdapter()]).adapt('AOEU').selferrors = ['Not lower case']
assert StringAdapter(adapters=[LowerCaseStringAdapter()]).adapt('AOEU').data == 'aoeu'

I would like to be able to, say, chain a validator. followed by an adapter, followed by a validator. For example:

StringAdapter(validators=(is_numeric, cast_int, greater_than(0))

Now this is just a toy example that is likely better served by an IntegerAdapter, but I think retaining this flexibility would be valuable compared to what I see as a rather artificial distinction between validation and cleanup.

LilyFoote avatar Mar 07 '18 23:03 LilyFoote

Another thing that we need to consider is how to modify an existing field. The simplest option to implement is allowing direct replacement of a field, but more targeted changes might be more user-friendly. This might be best as part of a higher level API wrapping the simple replacement primitive.

LilyFoote avatar Mar 07 '18 23:03 LilyFoote

My bad, actually your request is possible with the new tut

I would like to be able to, say, chain a validator. followed by an adapter, followed by a validator.

Yes we can add this:

StringAdapter(adapters=(is_numeric, cast_int, greater_than(0))

In that spec adapters is a list of Adapter objects, and when you add them there would be some magic type() action.

Instead of .adapters, perhaps we could rename it .chain ?

jpic avatar Mar 08 '18 11:03 jpic

Yes i completely dig you example:

StringAdapter(chain=(IntAdapter.steps('validate'), IntAdapter(cast=True).steps('clean'), IntAdapter(min_value=0))

Would be the same as:

StringAdapter(chain=(IntAdapter(cast=True, min_value=0)))

But I'm a bit lost with how the IOC would work, I thought calling ModelFormAdapter.steps.validate() would chain validate() calls on each adapter. But I think should be able to work out nicely with the rest of the pattern, of course it's hard to be sure without doing some tests ... I think we're going to throw away a lot of code before we get to something :joy:

Perhaps you already see a way to adapt the new tutorial for this ?

jpic avatar Mar 08 '18 12:03 jpic

I've separated the concept of adapter and payload, is it better or worse ?

jpic avatar Mar 09 '18 10:03 jpic

I'm going to have to have a social life this weekend to keep me away from coding this :joy: :joy: :joy: It deprecates yourlabs/facond ^^

jpic avatar Mar 09 '18 11:03 jpic

Related comment: https://github.com/yourlabs/django-autocomplete-light/pull/983#issuecomment-371982751

jpic avatar Mar 12 '18 10:03 jpic