-
Notifications
You must be signed in to change notification settings - Fork 34
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
Allow abstract subclasses of ModelSchema #63
base: main
Are you sure you want to change the base?
Changes from all commits
3fd4198
686e011
61a7ea0
0a3784a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,33 @@ class UserSchema(ModelSchema): | |
|
||
Once defined, the `UserSchema` can be used to perform various functions on the underlying Django model object, such as generating JSON schemas or exporting serialized instance data. | ||
|
||
### Custom subclasses | ||
|
||
Abstract subclasses can be defined to implement methods shared over for a number of ModelSchemata, note that they cannot be instantiated by themselves. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename |
||
|
||
```python | ||
from typing import Optional | ||
from django.db.models import Model | ||
from djantic import ModelSchema | ||
from myapp.models import User | ||
|
||
class BaseModelSchema(ModelSchema): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you make more obvious that this is an example and what the use-case is? This may be misinterpreted of how to define all abstract schema. For example, the |
||
class Config: | ||
model: Optional[Model] = None | ||
abstract = True | ||
|
||
def to_django(self) -> Model: | ||
if self.Config.model is not None: | ||
return self.Config.model.objects.create(**self.dict()) | ||
raise NotImplementedError() | ||
|
||
class CreateUserSchema(BaseModelSchema): | ||
class Config: | ||
model = User | ||
|
||
``` | ||
|
||
|
||
### Basic schema usage | ||
|
||
The `UserSchema` above can be used to generate a JSON schema using Pydantic's [schema](https://pydantic-docs.helpmanual.io/usage/schema/) method: | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,23 @@ class Config: | |
include = ["id"] | ||
exclude = ["first_name"] | ||
|
||
class AbstractModelSchema(ModelSchema): | ||
class Config: | ||
abstract = True | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is expected to happen when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a very good point, I'll ping you once I have a minute to look into it. In my opinion none of those should be present on an abstract model, as its main raison d'etre is to reduce boilerplate and allow proper typing in codebases where multiple ModelSchemata are used in a similar customised manner. Do you have any thoughts on the matter as the repo/package owner? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess it would be best if we started out with some warnings (raise config error) if someone tries to include these on the abstract model to avoid confusion, then if someone later presented a valid use-case to support any of these then maybe could do then if it made sense. |
||
|
||
with pytest.raises( | ||
ConfigError, | ||
match="Abstract ModelSchema cannot be instantiated.", | ||
): | ||
schema = AbstractModelSchema() | ||
|
||
class InheritedSchema(AbstractModelSchema): | ||
class Config: | ||
model = User | ||
include = ["id"] | ||
|
||
schema = InheritedSchema(id=1) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add specific assertions. |
||
|
||
|
||
@pytest.mark.django_db | ||
def test_get_field_names(): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes:
### Abstract schema models
Customizing the schema