openedx-learning 0.27.1__py2.py3-none-any.whl → 0.29.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. openedx_learning/__init__.py +1 -1
  2. openedx_learning/apps/authoring/backup_restore/api.py +19 -4
  3. openedx_learning/apps/authoring/backup_restore/management/commands/lp_dump.py +22 -4
  4. openedx_learning/apps/authoring/backup_restore/management/commands/lp_load.py +57 -0
  5. openedx_learning/apps/authoring/backup_restore/serializers.py +168 -0
  6. openedx_learning/apps/authoring/backup_restore/toml.py +203 -24
  7. openedx_learning/apps/authoring/backup_restore/zipper.py +1007 -16
  8. openedx_learning/apps/authoring/components/api.py +55 -0
  9. openedx_learning/apps/authoring/components/migrations/0004_remove_componentversioncontent_uuid.py +17 -0
  10. openedx_learning/apps/authoring/components/models.py +1 -3
  11. openedx_learning/apps/authoring/publishing/api.py +65 -12
  12. openedx_learning/apps/authoring/sections/api.py +17 -0
  13. openedx_learning/apps/authoring/subsections/api.py +17 -0
  14. openedx_learning/apps/authoring/units/api.py +17 -0
  15. {openedx_learning-0.27.1.dist-info → openedx_learning-0.29.0.dist-info}/METADATA +14 -5
  16. {openedx_learning-0.27.1.dist-info → openedx_learning-0.29.0.dist-info}/RECORD +21 -18
  17. openedx_tagging/core/tagging/models/base.py +7 -5
  18. openedx_tagging/core/tagging/models/utils.py +37 -9
  19. {openedx_learning-0.27.1.dist-info → openedx_learning-0.29.0.dist-info}/WHEEL +0 -0
  20. {openedx_learning-0.27.1.dist-info → openedx_learning-0.29.0.dist-info}/licenses/LICENSE.txt +0 -0
  21. {openedx_learning-0.27.1.dist-info → openedx_learning-0.29.0.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,9 @@
1
1
  """
2
2
  Utilities for tagging and taxonomy models
3
3
  """
4
- from django.db.models import Aggregate, CharField
5
- from django.db.models.expressions import Func
4
+ from django.db import connection as db_connection
5
+ from django.db.models import Aggregate, CharField, TextField
6
+ from django.db.models.expressions import Combinable, Func
6
7
 
7
8
  RESERVED_TAG_CHARS = [
8
9
  '\t', # Used in the database to separate tag levels in the "lineage" field
@@ -34,21 +35,48 @@ class ConcatNull(Func): # pylint: disable=abstract-method
34
35
  )
35
36
 
36
37
 
37
- class StringAgg(Aggregate): # pylint: disable=abstract-method
38
+ class StringAgg(Aggregate, Combinable):
38
39
  """
39
40
  Aggregate function that collects the values of some column across all rows,
40
- and creates a string by concatenating those values, with "," as a separator.
41
+ and creates a string by concatenating those values, with a specified separator.
41
42
 
42
- This is the same as Django's django.contrib.postgres.aggregates.StringAgg,
43
- but this version works with MySQL and SQLite.
43
+ This version supports PostgreSQL (STRING_AGG), MySQL (GROUP_CONCAT), and SQLite.
44
44
  """
45
+ # Default function is for MySQL (GROUP_CONCAT)
45
46
  function = 'GROUP_CONCAT'
46
47
  template = '%(function)s(%(distinct)s%(expressions)s)'
47
48
 
48
- def __init__(self, expression, distinct=False, **extra):
49
+ def __init__(self, expression, distinct=False, delimiter=',', **extra):
50
+ self.delimiter = delimiter
51
+ # Handle the distinct option and output type
52
+ distinct_str = 'DISTINCT ' if distinct else ''
53
+
54
+ extra.update({
55
+ 'distinct': distinct_str,
56
+ 'output_field': CharField(),
57
+ })
58
+
59
+ # Check the database backend (PostgreSQL, MySQL, or SQLite)
60
+ if 'postgresql' in db_connection.vendor.lower():
61
+ self.function = 'STRING_AGG'
62
+ self.template = "%(function)s(%(distinct)s%(expressions)s::TEXT, '%(delimiter)s')"
63
+ extra.update({
64
+ "delimiter": self.delimiter,
65
+ "output_field": TextField(),
66
+ })
67
+
68
+ # Initialize the parent class with the necessary parameters
49
69
  super().__init__(
50
70
  expression,
51
- distinct='DISTINCT ' if distinct else '',
52
- output_field=CharField(),
53
71
  **extra,
54
72
  )
73
+
74
+ # Implementing abstract methods from Combinable
75
+ def __rand__(self, other):
76
+ return self._combine(other, 'AND', False)
77
+
78
+ def __ror__(self, other):
79
+ return self._combine(other, 'OR', False)
80
+
81
+ def __rxor__(self, other):
82
+ return self._combine(other, 'XOR', False)