ob-dj-store 0.0.12__tar.gz → 0.0.12.2__tar.gz

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 (157) hide show
  1. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/PKG-INFO +1 -1
  2. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/config/settings.py +26 -2
  3. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/stores/rest/serializers/serializers.py +88 -46
  4. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_favorite.py +6 -7
  5. ob-dj-store-0.0.12.2/ob_dj_store/core/stores/settings_validation.py +88 -0
  6. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store.egg-info/PKG-INFO +1 -1
  7. ob-dj-store-0.0.12/ob_dj_store/core/stores/settings_validation.py +0 -45
  8. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/.github/dependabot.yml +0 -0
  9. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/.github/workflows/docs.yml +0 -0
  10. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/.github/workflows/pre-release.yml +0 -0
  11. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/.github/workflows/release.yml +0 -0
  12. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/.github/workflows/test-build.yml +0 -0
  13. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/.gitignore +0 -0
  14. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/.isort.cfg +0 -0
  15. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/.pre-commit-config.yaml +0 -0
  16. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/Dockerfile +0 -0
  17. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/MANIFEST.in +0 -0
  18. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/Makefile +0 -0
  19. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/Pipfile +0 -0
  20. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/Pipfile.lock +0 -0
  21. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/README.md +0 -0
  22. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/config/__init__.py +0 -0
  23. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/config/urls.py +0 -0
  24. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/config/wsgi.py +0 -0
  25. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docker-compose.env +0 -0
  26. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docker-compose.yml +0 -0
  27. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docs/Makefile +0 -0
  28. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docs/make.bat +0 -0
  29. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docs/source/admin.rst +0 -0
  30. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docs/source/conf.py +0 -0
  31. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docs/source/index.rst +0 -0
  32. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docs/source/installation.rst +0 -0
  33. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docs/source/models.rst +0 -0
  34. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/docs/source/rest_endpoints.rst +0 -0
  35. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/fixtures/initial_users.yaml +0 -0
  36. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/fixtures/stores.yaml +0 -0
  37. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/manage.py +0 -0
  38. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/__init__.py +0 -0
  39. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/__init__.py +0 -0
  40. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/stores/__init__.py +0 -0
  41. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/stores/filters.py +0 -0
  42. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/stores/urls.py +0 -0
  43. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/stores/views.py +0 -0
  44. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/tap/__init__.py +0 -0
  45. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/tap/serializers.py +0 -0
  46. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/tap/urls.py +0 -0
  47. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/apis/tap/views.py +0 -0
  48. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/__init__.py +0 -0
  49. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/__init__.py +0 -0
  50. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/admin.py +0 -0
  51. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/admin_inlines.py +0 -0
  52. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/apps.py +0 -0
  53. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/__init__.py +0 -0
  54. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/__init__.py +0 -0
  55. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/admin.py +0 -0
  56. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/apps.py +0 -0
  57. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/managers.py +0 -0
  58. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/migrations/0001_initial.py +0 -0
  59. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/migrations/0002_auto_20220815_1610.py +0 -0
  60. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/migrations/0003_auto_20220818_1938.py +0 -0
  61. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/migrations/__init__.py +0 -0
  62. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/models.py +0 -0
  63. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/gateway/tap/utils.py +0 -0
  64. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/managers.py +0 -0
  65. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0001_initial.py +0 -0
  66. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0002_auto_20220422_0205.py +0 -0
  67. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0003_openinghours.py +0 -0
  68. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0004_auto_20220422_2326.py +0 -0
  69. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0005_auto_20220425_2119.py +0 -0
  70. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0005_auto_20220427_1729.py +0 -0
  71. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0006_auto_20220428_0100.py +0 -0
  72. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0007_cart_cartitem_order_orderitem.py +0 -0
  73. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0008_order_status.py +0 -0
  74. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0009_auto_20220508_2142.py +0 -0
  75. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0010_auto_20220509_1633.py +0 -0
  76. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0011_favorite.py +0 -0
  77. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0012_auto_20220514_0633.py +0 -0
  78. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0013_auto_20220518_1539.py +0 -0
  79. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0014_auto_20220519_0018.py +0 -0
  80. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0015_inventory_inventoryoperations.py +0 -0
  81. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0016_productvariant_preparation_time.py +0 -0
  82. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0017_auto_20220524_0912.py +0 -0
  83. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0018_auto_20220524_1613.py +0 -0
  84. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0019_product_is_featured.py +0 -0
  85. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0020_orderhistory.py +0 -0
  86. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0021_auto_20220531_1849.py +0 -0
  87. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0022_order_pickup_time.py +0 -0
  88. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0023_feedback_feedbackattribute_feedbackconfig.py +0 -0
  89. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0024_auto_20220609_1552.py +0 -0
  90. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0025_productvariant_is_primary.py +0 -0
  91. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0026_auto_20220630_1913.py +0 -0
  92. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0027_auto_20220713_1759.py +0 -0
  93. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0028_phonecontact.py +0 -0
  94. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0029_auto_20220726_1750.py +0 -0
  95. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0030_category_parent.py +0 -0
  96. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0031_auto_20220811_1733.py +0 -0
  97. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0032_auto_20220812_1951.py +0 -0
  98. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0033_auto_20220815_0133.py +0 -0
  99. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0034_auto_20220815_1528.py +0 -0
  100. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0035_auto_20220818_1938.py +0 -0
  101. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0036_productattribute_is_mandatory.py +0 -0
  102. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0037_auto_20220825_1736.py +0 -0
  103. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0038_cartitem_extra_infos.py +0 -0
  104. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0039_auto_20220831_1521.py +0 -0
  105. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0040_auto_20220902_1806.py +0 -0
  106. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0041_auto_20220912_1506.py +0 -0
  107. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0042_wallet_wallettransaction.py +0 -0
  108. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0043_auto_20220919_1854.py +0 -0
  109. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0044_remove_productvariant_has_inventory.py +0 -0
  110. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0045_shippingmethod_type.py +0 -0
  111. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0046_auto_20221014_1720.py +0 -0
  112. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0047_auto_20221018_1433.py +0 -0
  113. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0048_auto_20221026_1933.py +0 -0
  114. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0049_auto_20221029_1524.py +0 -0
  115. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0050_favoriteextra.py +0 -0
  116. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0051_order_car_id.py +0 -0
  117. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0052_auto_20221129_1732.py +0 -0
  118. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0053_inventory_plu.py +0 -0
  119. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0054_auto_20221230_1501.py +0 -0
  120. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0055_store_image.py +0 -0
  121. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0056_auto_20230213_2224.py +0 -0
  122. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0057_auto_20230214_1724.py +0 -0
  123. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0058_attributechoice_is_default.py +0 -0
  124. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0059_auto_20230217_2006.py +0 -0
  125. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0060_alter_orderitem_product_variant.py +0 -0
  126. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0061_auto_20230223_1435.py +0 -0
  127. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0062_auto_20230226_2005.py +0 -0
  128. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0063_alter_store_payment_methods.py +0 -0
  129. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0064_auto_20230228_1814.py +0 -0
  130. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0065_auto_20230228_1932.py +0 -0
  131. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0066_auto_20230304_1532.py +0 -0
  132. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0067_auto_20230309_2014.py +0 -0
  133. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/0068_auto_20230309_2251.py +0 -0
  134. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/migrations/__init__.py +0 -0
  135. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/__init__.py +0 -0
  136. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_address.py +0 -0
  137. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_cart.py +0 -0
  138. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_feedback.py +0 -0
  139. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_inventory.py +0 -0
  140. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_order.py +0 -0
  141. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_payment.py +0 -0
  142. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_product.py +0 -0
  143. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_store.py +0 -0
  144. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/models/_wallet.py +0 -0
  145. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/receivers.py +0 -0
  146. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/core/stores/utils.py +0 -0
  147. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/utils/__init__.py +0 -0
  148. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/utils/helpers.py +0 -0
  149. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/utils/model.py +0 -0
  150. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store/utils/utils.py +0 -0
  151. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store.egg-info/SOURCES.txt +0 -0
  152. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store.egg-info/dependency_links.txt +0 -0
  153. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store.egg-info/requires.txt +0 -0
  154. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/ob_dj_store.egg-info/top_level.txt +0 -0
  155. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/pytest.ini +0 -0
  156. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/setup.cfg +0 -0
  157. {ob-dj-store-0.0.12 → ob-dj-store-0.0.12.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ob-dj-store
3
- Version: 0.0.12
3
+ Version: 0.0.12.2
4
4
  Summary: OBytes django application for managing ecommerce stores.
5
5
  Home-page: https://www.obytes.com/
6
6
  Author: OBytes
@@ -356,9 +356,33 @@ DIGITAL_PRODUCTS_REQUIRED_KEYS = (
356
356
 
357
357
 
358
358
  # Favorite Settings
359
+ MULTIPLE_FAVORITE_EXTRA = 1
360
+ SIGNLE_FAVORITE_EXTRA = 0
361
+ FAVORITE_TYPES = {
362
+ "Store": {
363
+ "path": "ob_dj_store.core.stores.models._store.Store",
364
+ },
365
+ "Product": {
366
+ "path": "ob_dj_store.core.stores.models._product.Product",
367
+ "extras": {
368
+ "AttributeChoice": {
369
+ "path": "ob_dj_store.core.stores.models._product.AttributeChoice",
370
+ "type": MULTIPLE_FAVORITE_EXTRA,
371
+ },
372
+ "ProductVariant": {
373
+ "path": "ob_dj_store.core.stores.models._product.ProductVariant",
374
+ "type": SIGNLE_FAVORITE_EXTRA,
375
+ },
376
+ },
377
+ },
378
+ }
379
+ FAVORITES_SERIALIZERS_PATHS = {
380
+ "Product": "ob_dj_store.apis.stores.rest.serializers.serializers.ProductSerializer",
381
+ "Store": "ob_dj_store.apis.stores.rest.serializers.serializers.StoreSerializer",
382
+ "AttributeChoice": "ob_dj_store.apis.stores.rest.serializers.serializers.AttributeChoiceSerializer",
383
+ "ProductVariant": "ob_dj_store.apis.stores.rest.serializers.serializers.ProductVariantSerializer",
384
+ }
359
385
 
360
- FAVORITE_TYPES = ("Store", "Product")
361
- EXTRA_FAVORITE_TYPES = ("AttributeChoice",)
362
386
 
363
387
  ESTIMATED_DELIVERING_TIME = 10 # in minutes
364
388
  DIFFERENT_STORE_ORDERING = False
@@ -1,5 +1,4 @@
1
1
  import calendar
2
- import sys
3
2
  import typing
4
3
  from datetime import time, timedelta
5
4
 
@@ -7,7 +6,9 @@ from django.conf import settings
7
6
  from django.contrib.contenttypes.models import ContentType
8
7
  from django.contrib.gis.geos import Point
9
8
  from django.core.exceptions import ObjectDoesNotExist, ValidationError
9
+ from django.db import models
10
10
  from django.shortcuts import get_object_or_404
11
+ from django.utils.module_loading import import_string
11
12
  from django.utils.timezone import now
12
13
  from django.utils.translation import gettext_lazy as _
13
14
  from rest_framework import serializers
@@ -963,18 +964,25 @@ class GenericSerializer(serializers.Serializer):
963
964
  return serializer_class(context=context).to_representation(value)
964
965
 
965
966
  def get_serializer_for_instance(self, instance):
966
- serializer_class = instance.__class__.__name__ + "Serializer"
967
- if hasattr(sys.modules[__name__], serializer_class):
968
- return getattr(sys.modules[__name__], serializer_class)
969
- else:
970
- raise NameError(_(f"name '{serializer_class}' is not defined"))
967
+ serializer_class = instance.__class__.__name__
968
+ return import_string(
969
+ store_settings.FAVORITES_SERIALIZERS_PATHS[serializer_class]
970
+ )
971
+
972
+
973
+ def get_favorite_extras_models():
974
+ extras_list = []
975
+ for key, value in settings.FAVORITE_TYPES.items():
976
+ if "extras" in value:
977
+ extras_list.extend(value["extras"].keys())
978
+ return extras_list
971
979
 
972
980
 
973
981
  class FavoriteExtraSerializer(serializers.ModelSerializer):
974
982
  content_object = GenericSerializer(read_only=True)
975
983
  object_id = serializers.IntegerField(min_value=1, write_only=True)
976
984
  object_type = serializers.ChoiceField(
977
- write_only=True, choices=store_settings.EXTRA_FAVORITE_TYPES
985
+ write_only=True, choices=get_favorite_extras_models()
978
986
  )
979
987
 
980
988
  class Meta:
@@ -986,13 +994,23 @@ class FavoriteExtraSerializer(serializers.ModelSerializer):
986
994
  "object_type",
987
995
  )
988
996
 
997
+ def to_representation(self, instance):
998
+ data = super().to_representation(instance)
999
+ extras = get_favorite_extras_models()
1000
+ model_name = instance.content_type.model
1001
+ for extra in extras:
1002
+ if model_name == extra.lower():
1003
+ data["object_type"] = extra
1004
+ break
1005
+ return data
1006
+
989
1007
 
990
1008
  class FavoriteSerializer(serializers.ModelSerializer):
991
1009
  content_object = GenericSerializer(read_only=True)
992
1010
  extras = FavoriteExtraSerializer(many=True)
993
1011
  object_id = serializers.IntegerField(min_value=1, write_only=True)
994
1012
  object_type = serializers.ChoiceField(
995
- write_only=True, choices=store_settings.FAVORITE_TYPES
1013
+ write_only=True, choices=list(store_settings.FAVORITE_TYPES.keys())
996
1014
  )
997
1015
 
998
1016
  class Meta:
@@ -1009,63 +1027,87 @@ class FavoriteSerializer(serializers.ModelSerializer):
1009
1027
  "name": {"required": True},
1010
1028
  }
1011
1029
 
1030
+ def to_representation(self, instance):
1031
+ data = super().to_representation(instance)
1032
+ model_name = instance.content_type.model
1033
+ for favorite in store_settings.FAVORITE_TYPES.keys():
1034
+ if model_name == favorite.lower():
1035
+ data["object_type"] = favorite
1036
+ break
1037
+ return data
1038
+
1012
1039
  def _lookup_validation(self, data):
1013
- content_type = ContentType.objects.get_for_model(type(data["content_object"]))
1014
- extras_lookup_content_type = {}
1015
- for extra in data["extras"]:
1016
- content_type_extra = extra.model
1017
- extras_lookup_content_type[content_type_extra] = extra
1040
+ content_type = ContentType.objects.get_for_model(data["content_object"])
1018
1041
  queryset = Favorite.objects.filter(
1019
1042
  content_type=content_type,
1020
1043
  object_id=data["content_object"].id,
1021
1044
  user=self.context["request"].user,
1022
- )
1023
- for key in extras_lookup_content_type.keys():
1024
- queryset = queryset.filter(
1025
- extras__content_type=ContentType.objects.get_for_model(key),
1026
- extras__object_id__in=[
1027
- extra.id for extra in extras_lookup_content_type[key]
1028
- ],
1029
- )
1030
- if queryset.exists():
1045
+ ).prefetch_related("extras")
1046
+
1047
+ if not queryset.exists():
1048
+ return
1049
+
1050
+ for favorite in queryset:
1051
+ content_objects = [
1052
+ instance.content_object for instance in favorite.extras.all()
1053
+ ]
1054
+ if data["extras"] == content_objects:
1055
+ raise serializers.ValidationError(
1056
+ _(f"You cannot favorite the same item twice")
1057
+ )
1058
+
1059
+ def get_object(self, model: models.Model, id: int):
1060
+ try:
1061
+ object = model.objects.get(pk=id)
1062
+ return object
1063
+ except model.DoesNotExist:
1031
1064
  raise serializers.ValidationError(
1032
- _(f"You cannot favorite the same item twice")
1065
+ _(f"{model.__name__} with the id of {id} does not exist")
1033
1066
  )
1034
1067
 
1035
1068
  def validate(self, attrs):
1036
1069
  validated_data = super().validate(attrs)
1070
+ extras_data = {}
1037
1071
  name = validated_data["name"]
1038
1072
  object_type = validated_data["object_type"]
1039
- if object_type not in store_settings.FAVORITE_TYPES and hasattr(
1040
- sys.modules[__name__], object_type
1041
- ):
1042
- raise serializers.ValidationError(
1043
- _(f"Cannot resolve keyword '{object_type}' into an object type")
1044
- )
1045
- object_type_model = getattr(sys.modules[__name__], object_type)
1073
+ object_type_model = import_string(
1074
+ store_settings.FAVORITE_TYPES[object_type]["path"]
1075
+ )
1046
1076
  object_instance = get_object_or_404(
1047
1077
  object_type_model, pk=validated_data["object_id"]
1048
1078
  )
1049
- extras_data = {}
1050
- extras = []
1051
1079
  for extra in validated_data["extras"]:
1052
- extra_object_type = extra["object_type"]
1053
- if extra_object_type not in store_settings.EXTRA_FAVORITE_TYPES:
1080
+ if (
1081
+ extra["object_type"]
1082
+ not in store_settings.FAVORITE_TYPES[object_type]["extras"]
1083
+ ):
1054
1084
  raise serializers.ValidationError(
1055
- _(
1056
- f"Cannot resolve keyword '{extra_object_type}' into an object type"
1057
- )
1085
+ _(f"{extra['object_type']} Cannot be extra of {object_type}")
1058
1086
  )
1059
- extras_data.setdefault(extra_object_type, [])
1060
- extras_data[extra_object_type].append(extra["object_id"])
1061
- try:
1062
- for key in extras_data.keys():
1063
- model_class = getattr(sys.modules[__name__], key, None)
1064
- if model_class:
1065
- extras.append(model_class.objects.filter(id__in=extras_data[key]))
1066
- except ObjectDoesNotExist:
1067
- raise serializers.ValidationError(_("No matches the given query."))
1087
+ extra_object_type = extra["object_type"]
1088
+ extras_data.setdefault(
1089
+ extra_object_type,
1090
+ {
1091
+ "model": import_string(
1092
+ store_settings.FAVORITE_TYPES[object_type]["extras"][
1093
+ extra_object_type
1094
+ ]["path"]
1095
+ ),
1096
+ "ids": [],
1097
+ },
1098
+ )
1099
+ extras_data[extra_object_type]["ids"].append(extra["object_id"])
1068
1100
 
1101
+ extras = []
1102
+ for key, value in extras_data.items():
1103
+ type = store_settings.FAVORITE_TYPES[object_type]["extras"][key]["type"]
1104
+ if len(value["ids"]) > 1 and type == store_settings.SIGNLE_FAVORITE_EXTRA:
1105
+ raise serializers.ValidationError(_(f"Cannot set multiple {key}s"))
1106
+ for id in value["ids"]:
1107
+ extras.append(
1108
+ self.get_object(value["model"], id)
1109
+ ) # get objects of extras instead of ids
1110
+ extras = list(set(extras)) # remove duplicated extras
1069
1111
  validated_data = {
1070
1112
  "content_object": object_instance,
1071
1113
  "extras": extras,
@@ -44,13 +44,12 @@ class Favorite(DjangoModelCleanMixin, models.Model):
44
44
  )
45
45
  favorite.save()
46
46
  for extra in extras:
47
- for obj in extra:
48
- extra_content_type = ContentType.objects.get_for_model(type(obj))
49
- favorite.extras.create(
50
- content_type=extra_content_type,
51
- object_id=obj.id,
52
- content_object=obj,
53
- )
47
+ extra_content_type = ContentType.objects.get_for_model(type(extra))
48
+ favorite.extras.create(
49
+ content_type=extra_content_type,
50
+ object_id=extra.id,
51
+ content_object=extra,
52
+ )
54
53
  return favorite
55
54
 
56
55
 
@@ -0,0 +1,88 @@
1
+ from django.apps import apps
2
+ from django.core.checks import Error
3
+ from django.utils.module_loading import import_string
4
+
5
+ from config import settings
6
+
7
+ REQUIRED_INSTALLED_APPS = [
8
+ "rest_framework",
9
+ ]
10
+
11
+
12
+ def required_installed_apps(app_configs, **kwargs):
13
+ return [
14
+ Error(f"{app} is required in INSTALLED_APPS")
15
+ for app in REQUIRED_INSTALLED_APPS
16
+ if not apps.is_installed(app)
17
+ ]
18
+
19
+
20
+ def store_validation_settings(app_configs, **kwargs):
21
+ errors = []
22
+ if getattr(settings, "GIFT", None) and not getattr(
23
+ settings, "GIFT_PAYMENT_METHOD_PATH", None
24
+ ):
25
+ errors.append(
26
+ Error(
27
+ "GIFT_PAYMENT_METHOD_PATH must be set if GIFT is in Payment methods",
28
+ id="store_validation_settings_error",
29
+ )
30
+ )
31
+
32
+ def _path_validation(path):
33
+ try:
34
+ print(path)
35
+ path_class = import_string(path)
36
+ except ImportError:
37
+ errors.append(
38
+ Error(
39
+ f"{path} is not a valid path", id="store_validation_settings_error"
40
+ )
41
+ )
42
+
43
+ if hasattr(settings, "GIFT_PAYMENT_METHOD_PATH"):
44
+ _path_validation(settings.GIFT_PAYMENT_METHOD_PATH)
45
+
46
+ # Favorite validation settings
47
+ if hasattr(settings, "FAVORITE_TYPES"):
48
+ for key, favorite in settings.FAVORITE_TYPES.items():
49
+ if not favorite.get("path"):
50
+ errors.append(
51
+ Error(
52
+ f"Model path should be set for {key}",
53
+ id="store_validation_settings_error",
54
+ )
55
+ )
56
+ else:
57
+ _path_validation(favorite["path"])
58
+ if favorite.get("extras", None):
59
+ for key_extra, extra in favorite["extras"].items():
60
+ if not extra.get("path", None):
61
+ errors.append(
62
+ Error(
63
+ f"Model path should be set for {key}",
64
+ id="store_validation_settings_error",
65
+ )
66
+ )
67
+ else:
68
+ _path_validation(extra["path"])
69
+ if extra.get("type", None) == None:
70
+ errors.append(
71
+ Error(
72
+ f"type must be set for {key_extra}",
73
+ id="store_validation_settings_error",
74
+ )
75
+ )
76
+ else:
77
+ if not (
78
+ hasattr(settings, "SIGNLE_FAVORITE_EXTRA")
79
+ and hasattr(settings, "MULTIPLE_FAVORITE_EXTRA")
80
+ ):
81
+ errors.append(
82
+ Error(
83
+ f"SIGNLE_FAVORITE_EXTRA and MULTIPLE_FAVORITE_EXTRA must be set",
84
+ id="store_validation_settings_error",
85
+ )
86
+ )
87
+
88
+ return errors
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ob-dj-store
3
- Version: 0.0.12
3
+ Version: 0.0.12.2
4
4
  Summary: OBytes django application for managing ecommerce stores.
5
5
  Home-page: https://www.obytes.com/
6
6
  Author: OBytes
@@ -1,45 +0,0 @@
1
- from django.apps import apps
2
- from django.core.checks import Error
3
- from django.utils.module_loading import import_string
4
-
5
- from config import settings
6
-
7
- REQUIRED_INSTALLED_APPS = [
8
- "rest_framework",
9
- ]
10
-
11
-
12
- def required_installed_apps(app_configs, **kwargs):
13
- return [
14
- Error(f"{app} is required in INSTALLED_APPS")
15
- for app in REQUIRED_INSTALLED_APPS
16
- if not apps.is_installed(app)
17
- ]
18
-
19
-
20
- def store_validation_settings(app_configs, **kwargs):
21
- errors = []
22
- if getattr(settings, "GIFT", None) and not getattr(
23
- settings, "GIFT_PAYMENT_METHOD_PATH", None
24
- ):
25
- errors.append(
26
- Error(
27
- "GIFT_PAYMENT_METHOD_PATH must be set if GIFT is in Payment methods",
28
- id="store_validation_settings_error",
29
- )
30
- )
31
-
32
- def _path_validation(path):
33
- try:
34
- print(path)
35
- path_class = import_string(path)
36
- except ImportError:
37
- errors.append(
38
- Error(
39
- f"{path} is not a valid path", id="store_validation_settings_error"
40
- )
41
- )
42
-
43
- if getattr(settings, "GIFT_PAYMENT_METHOD_PATH", None):
44
- _path_validation(settings.GIFT_PAYMENT_METHOD_PATH)
45
- return errors
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes