Advertisement
Guest User

Untitled

a guest
Jun 16th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.59 KB | None | 0 0
  1. """
  2. Json Schema to Django Model
  3. """
  4. import json
  5. import argparse
  6. import logging
  7. import os
  8.  
  9.  
  10. def determine_model_name(model_id=None, filename=None):
  11. """
  12. Get the model name
  13. :param model_id: str, model id
  14. :param filename: str, filename
  15. :return: str, model name
  16. """
  17. model_name = ''
  18. if model_id:
  19. try:
  20. model_name = model_id.split('/')[-1].replace('.json', '')
  21. except Exception as e:
  22. logging.exception("Unhandled exception {}".format(e))
  23.  
  24. if not model_name and filename:
  25. filename = filename.strip(os.sep)
  26. model_name = filename.split(os.sep)[-1]
  27. model_name = model_name.split('.')[0]
  28.  
  29. return model_name.capitalize() or 'UnknownModel'
  30.  
  31.  
  32. def get_required_string(key_name, required_fields, field_type='string', is_pk_field=False):
  33. """
  34. Gets the required portion of model field
  35. :param key_name:
  36. :param required_fields:
  37. :return: str, required model string
  38. """
  39. if is_pk_field:
  40. return 'primary_key=True'
  41.  
  42. if field_type in ('number', 'array', 'object'):
  43. if key_name in required_fields:
  44. return 'null=False'
  45. return 'null=True'
  46. else: # string, boolean
  47. if key_name in required_fields:
  48. return 'null=False, blank=False'
  49. return 'null=True, blank=True'
  50.  
  51.  
  52. def parse_model():
  53. parser = argparse.ArgumentParser()
  54. parser.add_argument('filename')
  55. args = parser.parse_args()
  56. filename = args.filename
  57.  
  58. with open(filename) as f:
  59. json_model = json.load(f)
  60.  
  61. # Make sure not list, but object
  62. if json_model['type'] != 'object':
  63. print("Model type has to be object to convert to model, got {}".format(json_model['type']))
  64.  
  65. if 'oneOf' in json_model:
  66. print("Optional required fields detected: {}".format(json_model['oneOf']))
  67.  
  68. # Default model string
  69. model_str = "\nfrom djongo import models\nfrom djongo.models import json\n\n"
  70.  
  71. model_name = determine_model_name(json_model.get('id'), args.filename)
  72. model_str += "class {}(models.Model):\n".format(model_name)
  73. model_str += ' """Generated model from json schema"""\n'
  74. print("Model name is {}".format(model_name))
  75.  
  76. if 'title' in json_model:
  77. print("Title of model is {}".format(json_model['title']))
  78.  
  79. if 'description' in json_model:
  80. print("Description of model is {}".format(json_model['description']))
  81.  
  82. required_fields = []
  83. if 'required' in json_model:
  84. required_fields = json_model['required']
  85.  
  86. for key_name, key_attributes in json_model['properties'].items():
  87. if key_name.endswith('_id') and key_name != '_id':
  88. print("WARNING: Possible ForeignKey {}".format(key_name))
  89.  
  90. # if key_attributes['type'] == 'array':
  91. # print("ERROR: Unsupported type array, skipping for field {}".format(key_name))
  92.  
  93. if key_attributes['type'] == 'null':
  94. print("ERROR: Unsupported type null, skipping for field {}".format(key_name))
  95.  
  96. # PK field
  97. is_pk_field = False
  98. if key_name in ['id', '_id']:
  99. is_pk_field = True
  100.  
  101. # If required field
  102. required_str = get_required_string(key_name, required_fields, key_attributes['type'], is_pk_field)
  103. field_str = ''
  104.  
  105. # String choice field, enum
  106. if key_attributes['type'] == 'string' and 'enum' in key_attributes:
  107. if not key_attributes['enum']:
  108. print("ERROR: Missing enum for enum choice field {}, skipping..".format(key_name))
  109. continue
  110.  
  111. if len(key_attributes['enum']) == 1:
  112. print("WARNING: enum value with single choice for field {}, choice {}."
  113. "".format(key_name, key_attributes['enum']))
  114. continue
  115.  
  116. # Max length find
  117. max_length = 255
  118. for choice in key_attributes['enum']:
  119. if len(choice) > 255:
  120. max_length = len(choice)
  121.  
  122. choices = tuple(set(zip(key_attributes['enum'], key_attributes['enum'])))
  123.  
  124. field_str = " {} = models.CharField(choices={}, max_length={}, " \
  125. "default='{}', {})\n" \
  126. "".format(key_name, choices, max_length, key_attributes['enum'][0], required_str)
  127.  
  128. # Date time field
  129. elif key_attributes['type'] == 'string' and key_attributes.get('format') == 'date-time':
  130. auto_now_add = False
  131. editable = True
  132. if key_name in ['created_on', 'modified_on']:
  133. auto_now_add = True
  134. editable = False
  135.  
  136. field_str = " {} = models.DateTimeField(auto_now_add={}, editable={}, {})\n" \
  137. "".format(key_name, auto_now_add, editable, required_str)
  138.  
  139. elif key_attributes['type'] == 'string':
  140. field_str = " {} = models.TextField({})\n".format(key_name, required_str)
  141.  
  142. elif key_attributes['type'] == 'number':
  143. field_str = " {} = models.IntegerField({})\n".format(key_name, required_str)
  144.  
  145. elif key_attributes['type'] == 'array':
  146. field_str = " {} = json.JSONField(default=[], {})\n".format(key_name, required_str)
  147.  
  148. elif key_attributes['type'] == 'object':
  149. field_str = " {} = json.JSONField(default={{}}, {})\n".format(key_name, required_str)
  150.  
  151. elif key_attributes['type'] == 'boolean':
  152. field_str = " {} = models.BooleanField(default=False, {})\n".format(key_name, required_str)
  153.  
  154. model_str += field_str
  155.  
  156. model_str += "\n class Meta:\n db_table = '{}s'\n".format(model_name.lower())
  157.  
  158. print(model_str)
  159.  
  160.  
  161. if __name__ == "__main__":
  162. parse_model()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement