django-restit 4.1.38__py3-none-any.whl → 4.1.40__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.
account/models/group.py CHANGED
@@ -136,7 +136,7 @@ class Group(models.Model, RestModel, MetaDataModel):
136
136
  return self.restGet(request)
137
137
  return restPermissionDenied(request)
138
138
 
139
- def onRestCanSave(self, request):
139
+ def onRestCanSave(self, request=None, data=None, extended=None):
140
140
  if request.member is None:
141
141
  raise PermissionDeniedException("permission denied for save")
142
142
  if request.member.hasPermission(["manage_groups", "create_groups"]):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: django-restit
3
- Version: 4.1.38
3
+ Version: 4.1.40
4
4
  Summary: A Rest Framework for DJANGO
5
5
  License: MIT
6
6
  Author: Ian Starnes
@@ -17,7 +17,7 @@ account/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
17
17
  account/models/__init__.py,sha256=OxQbDkVcZogwgNj3bQWljOxAkkt15KgBYVrsumzek8Q,341
18
18
  account/models/device.py,sha256=UQVkwAX3zicSYRScPRn7StgBEm3NYM5K2X69IgCh4HQ,3756
19
19
  account/models/feeds.py,sha256=4n4Mv8HjcXpUmMPWafHlsGbVQ1fDKdtblL1hp30sDrg,1437
20
- account/models/group.py,sha256=Il3tcfqCueW9jsFDp7ziewCDx6EJqvrRwjR5ohepSRA,18212
20
+ account/models/group.py,sha256=a0H6DdexDE4E5vvxpB9HbUdUzKso22PtVGqJ2Bk2n5I,18243
21
21
  account/models/legacy.py,sha256=zYdtv4LC0ooxPVqWM-uToPwV-lYWQLorSE6p6yn1xDw,2720
22
22
  account/models/member.py,sha256=0AM6fZtLtgsdmIr-e_36t-PQkTZYnHZyj08dSj5pn94,47645
23
23
  account/models/membership.py,sha256=l7suW6kRCfa3KqdbqjOIO2jVhxjkPbEENdJIlj2WomY,7378
@@ -141,7 +141,7 @@ medialib/fixtures/medialib_test_fixture.json,sha256=7M7zvGI2S5G3ENV8OQ3Ks4149lEi
141
141
  medialib/forms.py,sha256=nrE6QTPNPiIeX7Nx4l9DEmAQeQXqFyCg1C3JEDBYJfE,5442
142
142
  medialib/migrations/0001_initial.py,sha256=H3JliH5aw7tiHef8MhrJr_9rGetqgA7UjTF-eKziRSM,20518
143
143
  medialib/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
- medialib/models.py,sha256=DnUpe-WyOHCU3vEfXlm_sodflUEgAterLTdLHo1RNe8,52121
144
+ medialib/models.py,sha256=QApiv3zFfqMSLbjVqwpvRYT4HKbXj7EZGFkNDG_P_hQ,52152
145
145
  medialib/ocr.py,sha256=zlP7-NBiXhW7jR9pljmEPl5xzLVZpLN5QLAELQgU0Fk,1189
146
146
  medialib/pdf.py,sha256=l28WwM0JKbT9boV-b_9TFh9jhvGcrquR8GqC8wfEaLk,1275
147
147
  medialib/qrcode.py,sha256=vHyA5egXOX70EFiUDgr1njI9zcF6bXQJ_hKAQrppRow,545
@@ -343,7 +343,7 @@ pushit/utils.py,sha256=IeTCGa-164nmB1jIsK1lu1O1QzUhS3BKfuXHGjCW-ck,2121
343
343
  rest/.gitignore,sha256=TbEvWRMnAiajCTOdhiNrd9eeCAaIjRp9PRjE_VkMM5g,118
344
344
  rest/README.md,sha256=V3ETc-cJu8PZIbKr9xSe_pA4JEUpC8Dhw4bQeVCDJPw,5460
345
345
  rest/RemoteEvents.py,sha256=nL46U7AuxIrlw2JunphR1tsXyqi-ep_gD9CYGpYbNgE,72
346
- rest/__init__.py,sha256=u1JmMJ5f6pBs8gdWElvXjCeVD9gkJ32PMVB28GZBm84,121
346
+ rest/__init__.py,sha256=qEmZBxIJWeZCVLWbDDx_XIDFv831Xv6nqEGRAnU33JA,121
347
347
  rest/arc4.py,sha256=y644IbF1ec--e4cUJ3KEYsewTCITK0gmlwa5mJruFC0,1967
348
348
  rest/cache.py,sha256=1Qg0rkaCJCaVP0-l5hZg2CIblTdeBSlj_0fP6vlKUpU,83
349
349
  rest/crypto/__init__.py,sha256=Tl0U11rgj1eBYqd6OXJ2_XSdNLumW_JkBZnaJqI6Ldw,72
@@ -358,7 +358,7 @@ rest/extra/__init__.py,sha256=YzmNsch5H5FFLkUK9mIAKyoRK_rJCA9HGb0kubp4h30,54
358
358
  rest/extra/json_metadata.py,sha256=p_ffzmANmOFix_oC3voR6_NNTjcn7-T7aXcH-I4_Npg,1078
359
359
  rest/fields.py,sha256=_v1TJVc6vyWlqmwFRJ6mtuR5Fo-lS0KcUhPWIrzKZUo,9719
360
360
  rest/forms.py,sha256=66Wm5cdy8tKib_mGicjq_yd-gNVMFWRECnrDksnNnwU,6316
361
- rest/helpers.py,sha256=oJ5jNW_JlG6_CD7jgBIF19aNh4Xi-avoQ38qr9Zl51E,26387
361
+ rest/helpers.py,sha256=-Gn-_eGVH0tMNBFJoDKR2lSA6FovFq_1SBDMt2zFm_0,26705
362
362
  rest/joke.py,sha256=0PpKaX2iN7jlS62kgjfmmqkFBYLPURz15aQ8R7OJkJ8,260
363
363
  rest/jwtoken.py,sha256=1ruZGPTXnodb85ywPd8ZmRiRYCskopA8EhcbX7Adixc,2298
364
364
  rest/log.py,sha256=hd1_4HBOS395sfXJIL6BTw9yekm1SLgBwYx_PdfIhKA,20930
@@ -375,7 +375,7 @@ rest/middleware/request.py,sha256=OlWE4_8nJ1krzuiNn2heecPxqtbTEhFzGYp3_7bnEEA,41
375
375
  rest/middleware/session.py,sha256=zHSoQpIzRLmpqr_JvW406wzpvU3W3gDbm5JhtzLAMlE,10240
376
376
  rest/middleware/session_store.py,sha256=X_i06TnZLW1srV0vkjjLhZ7fl1G56PswXxRpVzdFasw,1874
377
377
  rest/models/__init__.py,sha256=M8pvFDq-WCF-QcM58X7pMufYYe0aaQ3U0PwGe9TKbbY,130
378
- rest/models/base.py,sha256=1L5vXL1psmz3lp8dEDwAOzRb4x0uUwaSwmNbyYfmfR0,64288
378
+ rest/models/base.py,sha256=qDZR2-YelYnOz-3h-ssWGVDFvQ4ZYgbeU2SPRCsFDs4,65047
379
379
  rest/models/cacher.py,sha256=eKz8TINVhWEqKhJGMsRkKZTtBUIv5rN3NHbZwOC56Uk,578
380
380
  rest/models/metadata.py,sha256=GZTrDXms3jumo7dFq2zpY3x4EzGZWwryn5Jfsr6Wg2Y,11894
381
381
  rest/net.py,sha256=LTF4ip-ur8C2G7NETVOg7ioACegBGo4sDJA18PfF5kQ,1691
@@ -385,10 +385,10 @@ rest/rpc.py,sha256=8n6LdtUyLqpwvdH1dtVT1e2ODYxOj1CEYs8mm_-vqwA,3612
385
385
  rest/search.py,sha256=UPnUldROiq65KmnEn-FIsgnpxk0wcXVu7I2NGfB7A-Q,7645
386
386
  rest/serializers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
387
387
  rest/serializers/collection.py,sha256=7vDmuz6alautQVr9VsVCFQdQdJcZR9tkrOEs2b_mKQw,2015
388
- rest/serializers/csv.py,sha256=nae_SIIpDH7HReErjNacVxEujzTvJqQxHd29BY-RXh0,2975
388
+ rest/serializers/csv.py,sha256=CVD0erB2Ebl7mqgrMAZ2FxZSZpyVDCoSS4FHiEjuvDM,3252
389
389
  rest/serializers/excel.py,sha256=KtxqZZU5Huzo31tyVVWbshMudeSAImKLO71ufQQt0-c,1077
390
390
  rest/serializers/json.py,sha256=R1has2PZQuXacA6WwfdrBnMG4rSM6CrnXQOhGoAU6Dk,1736
391
- rest/serializers/legacy.py,sha256=AhwXFZQQ2XedV5ztQiHPbDRkd4vDX1iTejZrHH-r5Gs,61795
391
+ rest/serializers/legacy.py,sha256=LgU8Sr7yFoiOso1Tb-LkJ-vphGcbEc4BKuSCCuD62R8,61800
392
392
  rest/serializers/model.py,sha256=kbwtREE--n7YKUfTzErfYhHsgiuqnLdS52z1owrXaQI,7532
393
393
  rest/serializers/profiler.py,sha256=OxOimhEyvCAuzUBC9Q1dz2xaakjAqmSnekMATsjduXM,997
394
394
  rest/serializers/response.py,sha256=8PtxZznl8E_OQbCA1epIHcMxSJJYf9VOW_syXh19nz4,6509
@@ -474,7 +474,7 @@ ws4redis/servers/uwsgi.py,sha256=VyhoCI1DnVFqBiJYHoxqn5Idlf6uJPHvfBKgkjs34mo,172
474
474
  ws4redis/settings.py,sha256=K0yBiLUuY81iDM4Yr-k8hbvjn5VVHu5zQhmMK8Dtz0s,1536
475
475
  ws4redis/utf8validator.py,sha256=S0OlfjeGRP75aO6CzZsF4oTjRQAgR17OWE9rgZdMBZA,5122
476
476
  ws4redis/websocket.py,sha256=R0TUyPsoVRD7Y_oU7w2I6NL4fPwiz5Vl94-fUkZgLHA,14848
477
- django_restit-4.1.38.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
478
- django_restit-4.1.38.dist-info/METADATA,sha256=_DKFhVqRNHv4P29SNgPVaLhs87VnMIGj7pc3y9y7nFg,7573
479
- django_restit-4.1.38.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
480
- django_restit-4.1.38.dist-info/RECORD,,
477
+ django_restit-4.1.40.dist-info/LICENSE.md,sha256=VHN4hhEeVOoFjtG-5fVv4jesA4SWi0Z-KgOzzN6a1ps,1068
478
+ django_restit-4.1.40.dist-info/METADATA,sha256=Sm4DNuvkHqUeY2ZqBYmql_qo9BrmwWxp6Usuj02yjAU,7573
479
+ django_restit-4.1.40.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
480
+ django_restit-4.1.40.dist-info/RECORD,,
medialib/models.py CHANGED
@@ -409,7 +409,7 @@ class MediaItem(models.Model, RestModel, MetaDataModel):
409
409
  super(MediaItem, self).__init__(*args, **kwargs)
410
410
  self.old_state = self.state
411
411
 
412
- def onRestCanSave(self, request):
412
+ def onRestCanSave(self, request=None, data=None, extended=None):
413
413
  # must throw an exception if cannot save
414
414
  return True
415
415
 
rest/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  from .uberdict import UberDict # noqa: F401
2
2
  from .settings_helper import settings # noqa: F401
3
3
 
4
- __version__ = "4.1.38"
4
+ __version__ = "4.1.40"
rest/helpers.py CHANGED
@@ -124,6 +124,17 @@ def log_error(*args):
124
124
  getLoggerByRequest(request).error(*extra, *args)
125
125
 
126
126
 
127
+ def log_stack(*args):
128
+ request = getActiveRequest()
129
+ import inspect
130
+ extra = []
131
+ for frame in inspect.stack():
132
+ file, line, func = frame[1:4]
133
+ extra.append(f"{file}, line {line} in function {func}")
134
+ ERROR_LOGGER.error(*extra, *args)
135
+ getLoggerByRequest(request).error(*extra, *args)
136
+
137
+
127
138
  def setLogModel(self, component, pk):
128
139
  # this method allows for updating the component to associate a log with
129
140
  if not pk or (self._log_pk == pk):
rest/models/base.py CHANGED
@@ -418,7 +418,7 @@ class RestModel(object):
418
418
  obj = new_obj
419
419
  if using is None:
420
420
  using = self.restGetModelDB()
421
- obj.saveFromDict(None, value, using=using)
421
+ obj.checkPermsAndSave(None, value, using=using)
422
422
  # rh.log_print("{} vs {}".format(self._state.db, obj._state.db))
423
423
  # rh.log_print("saving FK to {} ({}.{}) - {}".format(fieldname, using, obj.pk, type(obj)), value)
424
424
  setattr(self, fieldname, obj)
@@ -468,7 +468,7 @@ class RestModel(object):
468
468
  def saveFromRequest(self, request, **kwargs):
469
469
  if "files" not in kwargs:
470
470
  kwargs["files"] = request.FILES
471
- return self.saveFromDict(request, request.DATA, **kwargs)
471
+ return self.checkPermsAndSave(request, request.DATA, **kwargs)
472
472
 
473
473
  def hasFieldChanged(self, fieldname):
474
474
  if not hasattr(self, "_changed__"):
@@ -489,17 +489,20 @@ class RestModel(object):
489
489
  else:
490
490
  self._changed__[fieldname] = old_value
491
491
 
492
- def saveFromDict(self, request, data, files=None, **kwargs):
492
+ def checkPermsAndSave(self, request, data, files=None, **kwargs):
493
493
  can_save = getattr(self.RestMeta, "CAN_SAVE", True)
494
494
  if not can_save:
495
- return self.restStatus(request, False, error="saving not allowed via rest for this model.")
496
- save_media_files = getattr(self.RestMeta, "SAVE_MEDIA_FILES", False) or getattr(self.RestMeta, "SAVE_MEDIA_FILES_BY_NAME", False)
495
+ raise re.PermissionDeniedException("saving not allowed via rest for this model.")
497
496
  # check check for save permissions
498
497
  if request is None:
499
498
  request = RestModel.getActiveRequest()
500
499
  if request is None:
501
500
  request = objict(member=None, FILES=[], DATA=objict(), is_authenticated=False, is_local=True)
502
- self.onRestCanSave(request)
501
+ self.onRestCanSave(request, data, kwargs)
502
+ return self.saveFromDict(request, data, files=None, **kwargs)
503
+
504
+ def saveFromDict(self, request, data, files=None, **kwargs):
505
+ save_media_files = getattr(self.RestMeta, "SAVE_MEDIA_FILES", False) or getattr(self.RestMeta, "SAVE_MEDIA_FILES_BY_NAME", False)
503
506
  is_new = self.id is None
504
507
  has_fields = hasattr(self.RestMeta, "SAVE_FIELDS") and len(self.RestMeta.SAVE_FIELDS)
505
508
  has_no_fields = hasattr(self.RestMeta, "NO_SAVE_FIELDS") and len(self.RestMeta.NO_SAVE_FIELDS)
@@ -516,9 +519,10 @@ class RestModel(object):
516
519
  else:
517
520
  m_field = field
518
521
  req_field = field
519
- req_value = getattr(request, req_field, None)
520
- if request and req_value:
521
- data[m_field] = req_value
522
+ if request is not None:
523
+ req_value = getattr(request, req_field, None)
524
+ if req_value is not None:
525
+ data[m_field] = req_value
522
526
  # rh.log_print(data)
523
527
  self._changed__ = objict()
524
528
  if hasattr(self.RestMeta, "POST_SAVE_FIELDS"):
@@ -561,7 +565,7 @@ class RestModel(object):
561
565
  if len(deferred):
562
566
  self.save(using=using)
563
567
 
564
- if len(rfiles) and save_media_files:
568
+ if rfiles is not None and len(rfiles) and save_media_files:
565
569
  self.restSaveMediaFiles(rfiles)
566
570
 
567
571
  # these setters are responsible for saving themselves
@@ -575,7 +579,7 @@ class RestModel(object):
575
579
  return self
576
580
 
577
581
  def restSaveFiles(self, request, files=None):
578
- if files is None:
582
+ if files is None and request is not None:
579
583
  files = request.FILES
580
584
  if not files:
581
585
  return files
@@ -728,10 +732,10 @@ class RestModel(object):
728
732
  self.on_rest_pre_get(request)
729
733
  return self.restGet(request)
730
734
 
731
- def onRestCanSave(self, request=None):
732
- self.onRestCheckSavePerms(request)
735
+ def onRestCanSave(self, request=None, data=None, extended=None):
736
+ self.onRestCheckSavePerms(request, data, extended)
733
737
 
734
- def onRestCheckSavePerms(self, request=None):
738
+ def onRestCheckSavePerms(self, request=None, data=None, extended=None):
735
739
  if request is None:
736
740
  request = self.getActiveRequest()
737
741
  if request is None:
@@ -748,7 +752,15 @@ class RestModel(object):
748
752
  group_field = getattr(self.RestMeta, "GROUP_FIELD", "group")
749
753
  # rh.log_error(F"group field={group_field}")
750
754
  if self.id is None:
751
- group = request.DATA.get(group_field)
755
+ group = None
756
+ if extended is not None:
757
+ group = extended.get(group_field, None)
758
+ if group is None:
759
+ if data is not None:
760
+ group = data.get(group_field, None)
761
+ if group is None:
762
+ if request is not None:
763
+ group = request.DATA.get(group_field, None)
752
764
  elif "__" in group_field and hasattr(self, "group"):
753
765
  group = self.group
754
766
  elif "__" in group_field:
@@ -764,11 +776,11 @@ class RestModel(object):
764
776
  if not status:
765
777
  if self.id is None and code == 402:
766
778
  code = 435
767
- rh.log_error(F"onRestCheckSavePerms: {self.id} {request.member} {group} permission denied: status={status}, error={error}, code={code}", perms)
779
+ rh.log_error(F"onRestCheckSavePerms: {self.__class__.__name__} {request.member} {group} permission denied: status={status}, error={error}, code={code}", perms)
768
780
  raise re.PermissionDeniedException(error, code)
769
781
 
770
782
  def on_rest_post(self, request):
771
- self.saveFromRequest(request)
783
+ self.checkPermsAndSave(request, request.DATA)
772
784
  status_only = request.DATA.get("status_only", False, field_type=bool)
773
785
  if status_only:
774
786
  return self.restStatus(request, True)
@@ -784,11 +796,12 @@ class RestModel(object):
784
796
  def on_rest_saved(self, request, is_new=False):
785
797
  pass
786
798
 
787
- def on_rest_delete(self, request):
799
+ def on_rest_delete(self, request, force=False):
788
800
  can_delete = getattr(self.RestMeta, "CAN_DELETE", False)
789
801
  if not can_delete:
790
802
  return self.restStatus(request, False, error="deletion not allowed via rest for this model.")
791
- self.onRestCanSave(request)
803
+ if not force:
804
+ self.onRestCanSave(request)
792
805
  self.on_rest_deleted(request)
793
806
  self.delete()
794
807
  RestModel._setupGraphHelpers()
@@ -1121,7 +1134,7 @@ class RestModel(object):
1121
1134
  try:
1122
1135
  obj = cls.ro_objects().filter(**item).last()
1123
1136
  if not obj:
1124
- obj.saveFromDict(request, item)
1137
+ obj.checkPermsAndSave(request, item)
1125
1138
  items.append(obj)
1126
1139
  except Exception:
1127
1140
  pass
rest/serializers/csv.py CHANGED
@@ -5,38 +5,42 @@ import csv
5
5
 
6
6
 
7
7
  def flattenObject(obj, field_names):
8
- NOT_FOUND = "-!@#$%^&*()-"
9
-
10
8
  row = []
11
9
  for f in field_names:
12
- d = getattr(obj, f, NOT_FOUND)
13
- if d != NOT_FOUND:
14
- if callable(d):
15
- d = d()
16
- elif "." in f:
17
- f1, f2 = f.split('.')
18
- d1 = getattr(obj, f1, None)
19
- if d1:
20
- if not hasattr(d1, f2):
21
- if hasattr(d1, "first"):
22
- d1 = d1.first()
23
- d = getattr(d1, f2, "")
10
+ d = ""
11
+ if "__" in f:
12
+ f = f.replace("__", ".")
13
+ if "." in f:
14
+ # we could use obj.getFieldValue
15
+ keys = f.split('.')
16
+ f1 = keys[0]
17
+ f2 = keys[1]
18
+ if f1 == "metadata" and hasattr(obj, "getProperty"):
19
+ if len(keys) > 2:
20
+ d = obj.getProperty(f2, category=keys[2])
21
+ else:
22
+ d = obj.getProperty(f2)
23
+ elif hasattr(obj, "getFieldValue"):
24
+ d = obj.getFieldValue(f, "t/a")
24
25
  if callable(d):
25
26
  d = d()
26
27
  else:
27
- d = ""
28
- elif "__" in f:
29
- f1, f2 = f.split('__')
30
- d1 = getattr(obj, f1, None)
31
- if d1:
32
- if not hasattr(d1, f2):
33
- if hasattr(d1, "first"):
34
- d1 = d1.first()
35
- d = getattr(d1, f2, "")
36
- else:
37
- d = ""
28
+ d1 = getattr(obj, f1, None)
29
+ if d1 is not None:
30
+ if not hasattr(d1, f2):
31
+ if hasattr(d1, "first"):
32
+ d1 = d1.first()
33
+ d = getattr(d1, f2, "")
34
+ if callable(d):
35
+ d = d()
38
36
  else:
37
+ d = getattr(obj, f, "n/a")
38
+ if callable(d):
39
+ d = d()
40
+ if d is None:
39
41
  d = "n/a"
42
+ elif hasattr(d, "pk"):
43
+ d = d.pk
40
44
  row.append(str(d))
41
45
  return row
42
46
 
@@ -226,6 +226,7 @@ class RawQuery(object):
226
226
  sql += " OFFSET %d" % self.offset
227
227
 
228
228
  return sql + ";"
229
+
229
230
  def run(self):
230
231
  return self.model.objects.raw(self.sql())
231
232