I have a Django==2.2.3
app with djangorestframework==3.9.4
and django-rest-swagger==2.2.0
. I wanted to have a single source of truth (for data validation as well as api-docs) for my api endpoints. I have a JSON that looks something like this
{
"get": {
"query_param1" : {
"type": "string",
"required": "false",
"message": "what does it do/what is it for?"
},
"query_param2" : {...},
"responseMessages": {
"code: 401": "Not authenticated",
"code: 403": "Insufficient rights to call this procedure"
}
},
"delete": {
"query_param1" : {...},
"query_param2" : {...},
"responseMessages": {...},
},
"put": {...},
"post": {...},
}
I created a json schema from this and the validation is working.
This json is converted to a yaml string which is used by django-rest-swagger
. How it uses the yaml is, you need to put the yaml in the doc strings. But I don't want to go and write the same thing for every thing. There will be many endpoints and writing the same thing for all those endpoints doesn't feel right.
So I figured if I make a base class and just send the json to that base class, it can create all the doc strings for me, using the json and put it dynamically to the required functions. I now face a blocker and it says.
AttributeError: attribute '__ doc __' of 'method' objects is not writable
This is how my class looks like
class Parent:
def __init__(self):
schema = json.load(schema_path)
self.get.__doc__ = convertToYaml(schema['get'])
**ERROR HERE: AttributeError: attribute '__doc__' of 'method' objects is not writable**
class Child(Parent)
def get(self):
JsonResponse({message: "Hi! I work fine" })
TLDR:
Error obtained: AttributeError: attribute __ doc __ of method objects is not writable
Question: How to change a children's class function's docstring from a parent class?
You could define it in the parent's __new__
method.
Here is a simple example of how you can override it.
class Parent(object):
""" This is the Parent"""
def __new__(cls):
cls.__init__.__doc__ = cls.__bases__[0].__doc__
return object.__new__(cls)
def __init__(self):
print('hello')
class Child(Parent):
""" This is the Child """
def __init__(self):
super().__init__()
test = Child()
print(test.__init__.__doc__)
In your example it would be this:
class Parent(object):
def __new__(cls):
schema = json.load(schema_path)
cls.get.__doc__ = convertToYaml(schema['get'])
return object.__new__(cls)