22import logging
33import uuid
44from abc import ABCMeta
5- from typing import Any , Optional , Tuple , Type , Union
5+ from typing import Any , List , Optional , Tuple , Type , Union
66
77from django .db import models
88from django .http import HttpRequest
@@ -27,6 +27,10 @@ def __init__(self, service=None): # type: ignore
2727 self .service = service
2828 super ().__init__ (model = self .model )
2929
30+ # Critical to set Meta
31+ if hasattr (self , "Meta" ):
32+ self .model .Meta = self .Meta # type: ignore
33+
3034 # Define Controller APIs for auto generation
3135 async def get_obj (self , request : HttpRequest , id : int ) -> Any :
3236 """
@@ -83,15 +87,18 @@ async def get_objs(
8387class CrudApiMetaclass (ABCMeta ):
8488 def __new__ (mcs , name : str , bases : Tuple [Type [Any ], ...], attrs : dict ) -> Any :
8589 # Get configs from Meta
86- temp_base : Type = type .__new__ (type , "object" , (), {})
8790 temp_cls : Type = super (CrudApiMetaclass , mcs ).__new__ (
88- mcs , name , (temp_base ,), attrs
91+ mcs , name , (object ,), attrs
8992 )
9093 temp_opts : ModelOptions = ModelOptions (getattr (temp_cls , "Meta" , None ))
94+ opts_model : Optional [Type [models .Model ]] = temp_opts .model
9195 opts_fields_exclude : Optional [str ] = temp_opts .model_exclude
9296 opts_fields : Optional [str ] = temp_opts .model_fields
93- opts_model : Optional [Type [models .Model ]] = temp_opts .model
9497 opts_recursive : Optional [bool ] = temp_opts .model_recursive
98+ opts_join : Optional [bool ] = temp_opts .model_join
99+ opts_sensitive_fields : Optional [
100+ Union [str , List [str ]]
101+ ] = temp_opts .sensitive_fields
95102
96103 base_cls_attrs = {
97104 "get_obj" : http_get ("/{id}" , summary = "Get a single object" )(
@@ -117,7 +124,6 @@ class Config:
117124 model_fields = "__all__"
118125 else :
119126 model_fields = opts_fields if opts_fields else "__all__"
120- model_recursive = opts_recursive
121127
122128 async def add_obj ( # type: ignore
123129 self , request : HttpRequest , data : DataSchema
@@ -137,7 +143,7 @@ async def patch_obj( # type: ignore
137143 ) -> Any :
138144 """
139145 PATCH /{id}
140- Update a single field for a Object
146+ Update a single object
141147 """
142148 if await self .service .patch_obj (id = id , payload = data .dict ()):
143149 return BaseApiResponse ("Updated." )
@@ -169,21 +175,35 @@ async def patch_obj( # type: ignore
169175 mcs , name , (new_base ,), attrs
170176 )
171177
172- new_cls .model = opts_model
173- new_cls .model_exclude = opts_fields_exclude
174- new_cls .model_fields = opts_fields
175- new_cls .model_recursive = opts_recursive
176-
178+ if opts_model :
179+ setattr (opts_model .Meta , "model_exclude" , opts_fields_exclude )
180+ setattr (opts_model .Meta , "model_fields" , opts_fields )
181+ setattr (opts_model .Meta , "model_recursive" , opts_recursive )
182+ setattr (opts_model .Meta , "model_join" , opts_join )
183+ setattr (opts_model .Meta , "sensitive_fields" , opts_sensitive_fields )
184+ setattr (new_cls , "model" , opts_model )
177185 return new_cls
178186
179187
180188class ModelOptions :
181189 def __init__ (self , options : object = None ):
190+ """
191+ Configuration:
192+ model: django model
193+ model_fields: fields to be included in Schema, default to "__all__"
194+ model_exclude: fields to be excluded in Schema
195+ model_join: retrieve all m2m/FK fields, default to True
196+ model_recursive: recursively retrieve FK models, default to False
197+ """
182198 self .model : Optional [Type [models .Model ]] = getattr (options , "model" , None )
183199 self .model_fields : Optional [Union [str ]] = getattr (options , "model_fields" , None )
184200 self .model_exclude : Optional [Union [str ]] = getattr (
185201 options , "model_exclude" , None
186202 )
203+ self .model_join : Optional [Union [bool ]] = getattr (options , "model_join" , True )
187204 self .model_recursive : Optional [Union [bool ]] = getattr (
188205 options , "model_recursive" , False
189206 )
207+ self .sensitive_fields : Optional [Union [str , List [str ]]] = getattr (
208+ options , "sensitive_fields" , ["token" , "password" ]
209+ )
0 commit comments