Package: ninja-schema
Ninja SchemaNinja Schema converts your Django ORM models to Pydantic schemas with more Pydantic features supported.Inspired by:django-ninjaanddjanticNoticeStarting version0.13.4, Ninja schema will support both v1 and v2 of pydantic library and will closely monitor V1 support on pydantic package.RequirementsPython >= 3.8
django >= 3
pydantic >= 1.6Key features:Custom Field Support: Ninja Schema converts django model to native pydantic types which gives you quick field validation out of the box. eg Enums, email, IPAddress, URLs, JSON, etcField Validator: Fields can be validated withmodel_validatorjust like pydanticvalidatororroot_validator.Installationpip install ninja-schemaExampleCheckout this sample project:https://github.com/eadwinCode/bookstoreapiConfiguration Propertiesmodel: Django Modelinclude: Fields to include,default: '__all__'. Please note that when include =__all__, model'sPKbecomes optionalexclude: Fields to exclude,default: set()optional: Fields to mark optional,default: set()optional = '__all__'will make all schema fields optionaldepth: defines depth to nested generated schema,default: 0model_validator(*args, **kwargs)model_validatoris a substitute forpydanticvalidatorused for pre and post fields validation.
There functionalities are the same. More infopydantic validatorsfromdjango.contrib.authimportget_user_modelfromninja_schemaimportModelSchema,model_validatorUserModel=get_user_model()classCreateUserSchema(ModelSchema):classConfig:model=UserModelinclude=['username','email','password']@model_validator('username')defvalidate_unique_username(cls,value_data:str)->str:ifUserModel.objects.filter(username__icontains=value_data).exists():raiseValueError('Username exists')returnvalue_datafrom_orm(cls, obj: Any)You can generate a schema instance from your django model instancefromtypingsimportOptionalfromdjango.contrib.authimportget_user_modelfromninja_schemaimportModelSchema,model_validatorUserModel=get_user_model()new_user=UserModel.objects.create_user(username='eadwin',email='eadwin@example.com',password='password',first_name='Emeka',last_name='Okoro')classUserSchema(ModelSchema):classConfig:model=UserModelinclude=['id','first_name','last_name','username','email']schema=UserSchema.from_orm(new_user)print(schema.json(indent=2){"id":1,"first_name":"Emeka","last_name":"Okoro","email":"eadwin@example.com","username":"eadwin",}apply(self, model_instance, **kwargs)You can transfer data from your ModelSchema to Django Model instance using theapplyfunction.
Theapplyfunction uses Pydantic model.dictfunction,dictfunction filtering that can be passed askwargsto the.applyfunction.For more info, visitPydantic model exportfromtypingsimportOptionalfromdjango.contrib.authimportget_user_modelfromninja_schemaimportModelSchema,model_validatorUserModel=get_user_model()new_user=UserModel.objects.create_user(username='eadwin',email='eadwin@example.com',password='password')classUpdateUserSchema(ModelSchema):classConfig:model=UserModelinclude=['first_name','last_name','username']optional=['username']# `username` is now optionalschema=UpdateUserSchema(first_name='Emeka',last_name='Okoro')schema.apply(new_user,exclude_none=True)assertnew_user.first_name=='Emeka'# Trueassertnew_user.username=='eadwin'# TrueGenerated Schema Samplefromdjango.contrib.authimportget_user_modelfromninja_schemaimportModelSchema,model_validatorUserModel=get_user_model()classUserSchema(ModelSchema):classConfig:model=UserModelinclude='__all__'depth=2print(UserSchema.schema()){"title":"UserSchema","type":"object","properties":{"id":{"title":"Id","extra":{},"type":"integer"},"password":{"title":"Password","maxLength":128,"type":"string"},"last_login":{"title":"Last Login","type":"string","format":"date-time"},"is_superuser":{"title":"Superuser Status","description":"Designates that this user has all permissions without explicitly assigning them.","default":false,"type":"boolean"},"username":{"title":"Username","description":"Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.","maxLength":150,"type":"string"},"first_name":{"title":"First Name","maxLength":150,"type":"string"},"last_name":{"title":"Last Name","maxLength":150,"type":"string"},"email":{"title":"Email Address","type":"string","format":"email"},"is_staff":{"title":"Staff Status","description":"Designates whether the user can log into this admin site.","default":false,"type":"boolean"},"is_active":{"title":"Active","description":"Designates whether this user should be treated as active. Unselect this instead of deleting accounts.","default":true,"type":"boolean"},"date_joined":{"title":"Date Joined","type":"string","format":"date-time"},"groups":{"title":"Groups","description":"The groups this user belongs to. A user will get all permissions granted to each of their groups.","type":"array","items":{"$ref":"#/definitions/Group"}},"user_permissions":{"title":"User Permissions","description":"Specific permissions for this user.","type":"array","items":{"$ref":"#/definitions/Permission"}}},"required":["password","username","groups","user_permissions"],"definitions":{"Permission":{"title":"Permission","type":"object","properties":{"id":{"title":"Id","extra":{},"type":"integer"},"name":{"title":"Name","maxLength":255,"type":"string"},"content_type_id":{"title":"Content Type","type":"integer"},"codename":{"title":"Codename","maxLength":100,"type":"string"}},"required":["name","content_type_id","codename"]},"Group":{"title":"Group","type":"object","properties":{"id":{"title":"Id","extra":{},"type":"integer"},"name":{"title":"Name","maxLength":150,"type":"string"},"permissions":{"title":"Permissions","type":"array","items":{"$ref":"#/definitions/Permission"}}},"required":["name","permissions"]}}}