m2m模型翻译
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
3.6 KiB

7 months ago
  1. #
  2. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  3. # not use this file except in compliance with the License. You may obtain
  4. # a copy of the License at
  5. #
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. #
  8. # Unless required by applicable law or agreed to in writing, software
  9. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  10. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  11. # License for the specific language governing permissions and limitations
  12. # under the License.
  13. import functools
  14. from .. import This, DatumInContext, JSONPath
  15. class SortedThis(This):
  16. """The JSONPath referring to the sorted version of the current object.
  17. Concrete syntax is '`sorted`' or [\\field,/field].
  18. """
  19. def __init__(self, expressions=None):
  20. self.expressions = expressions
  21. def _compare(self, left, right):
  22. left = DatumInContext.wrap(left)
  23. right = DatumInContext.wrap(right)
  24. for expr in self.expressions:
  25. field, reverse = expr
  26. l_datum = field.find(left)
  27. r_datum = field.find(right)
  28. if (not l_datum or not r_datum or
  29. len(l_datum) > 1 or len(r_datum) > 1 or
  30. l_datum[0].value == r_datum[0].value):
  31. # NOTE(sileht): should we do something if the expression
  32. # match multiple fields, for now ignore them
  33. continue
  34. elif l_datum[0].value < r_datum[0].value:
  35. return 1 if reverse else -1
  36. else:
  37. return -1 if reverse else 1
  38. return 0
  39. def find(self, datum):
  40. """Return sorted value of This if list or dict."""
  41. if isinstance(datum.value, dict) and self.expressions:
  42. return datum
  43. if isinstance(datum.value, dict) or isinstance(datum.value, list):
  44. key = (functools.cmp_to_key(self._compare)
  45. if self.expressions else None)
  46. return [DatumInContext.wrap(
  47. [value for value in sorted(datum.value, key=key)])]
  48. return datum
  49. def __eq__(self, other):
  50. return isinstance(other, Len)
  51. def __repr__(self):
  52. return '%s(%r)' % (self.__class__.__name__, self.expressions)
  53. def __str__(self):
  54. return '[?%s]' % self.expressions
  55. class Len(JSONPath):
  56. """The JSONPath referring to the len of the current object.
  57. Concrete syntax is '`len`'.
  58. """
  59. def find(self, datum):
  60. datum = DatumInContext.wrap(datum)
  61. try:
  62. value = len(datum.value)
  63. except TypeError:
  64. return []
  65. else:
  66. return [DatumInContext(value,
  67. context=None,
  68. path=Len())]
  69. def __eq__(self, other):
  70. return isinstance(other, Len)
  71. def __str__(self):
  72. return '`len`'
  73. def __repr__(self):
  74. return 'Len()'
  75. class Keys(JSONPath):
  76. """The JSONPath referring to the keys of the current object.
  77. Concrete syntax is '`keys`'.
  78. """
  79. def find(self, datum):
  80. datum = DatumInContext.wrap(datum)
  81. try:
  82. value = list(datum.value.keys())
  83. except Exception as e:
  84. return []
  85. else:
  86. return [DatumInContext(value[i],
  87. context=None,
  88. path=Keys()) for i in range (0, len(datum.value))]
  89. def __eq__(self, other):
  90. return isinstance(other, Keys)
  91. def __str__(self):
  92. return '`keys`'
  93. def __repr__(self):
  94. return 'Keys()'