djgentelella 0.5.0__py3-none-any.whl → 0.5.2__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 (43) hide show
  1. djgentelella/__init__.py +1 -1
  2. djgentelella/admin.py +34 -1
  3. djgentelella/firmador_digital/models.py +16 -39
  4. djgentelella/history/api.py +142 -0
  5. djgentelella/history/filterset.py +23 -0
  6. djgentelella/history/serializers.py +50 -0
  7. djgentelella/history/utils.py +70 -0
  8. djgentelella/locale/es/LC_MESSAGES/django.mo +0 -0
  9. djgentelella/locale/es/LC_MESSAGES/django.po +38 -0
  10. djgentelella/locale/es/LC_MESSAGES/djangojs.mo +0 -0
  11. djgentelella/locale/es/LC_MESSAGES/djangojs.po +37 -0
  12. djgentelella/migrations/0017_alter_chunkedupload_status.py +18 -0
  13. djgentelella/migrations/0018_alter_chunkedupload_status.py +18 -0
  14. djgentelella/models.py +3 -2
  15. djgentelella/static/djgentelella.flags.vendors.min.css +1 -1
  16. djgentelella/static/vendors/bootstrap-datetimepicker/bootstrap-datetimepicker.min.css.map +7 -75
  17. djgentelella/static/vendors/flags/1x1/ac.svg +7 -75
  18. djgentelella/static/vendors/flags/1x1/cp.svg +7 -75
  19. djgentelella/static/vendors/flags/1x1/dg.svg +7 -75
  20. djgentelella/static/vendors/flags/1x1/ea.svg +7 -75
  21. djgentelella/static/vendors/flags/1x1/es-ct.svg +7 -75
  22. djgentelella/static/vendors/flags/1x1/es-ga.svg +7 -75
  23. djgentelella/static/vendors/flags/1x1/ic.svg +7 -75
  24. djgentelella/static/vendors/flags/1x1/ta.svg +7 -75
  25. djgentelella/static/vendors/flags/1x1/xx.svg +7 -75
  26. djgentelella/static/vendors/flags/4x3/ac.svg +7 -75
  27. djgentelella/static/vendors/flags/4x3/cp.svg +7 -75
  28. djgentelella/static/vendors/flags/4x3/dg.svg +7 -75
  29. djgentelella/static/vendors/flags/4x3/ea.svg +7 -75
  30. djgentelella/static/vendors/flags/4x3/es-ct.svg +7 -75
  31. djgentelella/static/vendors/flags/4x3/es-ga.svg +7 -75
  32. djgentelella/static/vendors/flags/4x3/ic.svg +7 -75
  33. djgentelella/static/vendors/flags/4x3/ta.svg +7 -75
  34. djgentelella/static/vendors/flags/4x3/xx.svg +7 -75
  35. djgentelella/trash/api.py +19 -0
  36. djgentelella/trash/serializer.py +1 -1
  37. djgentelella/urls.py +5 -1
  38. {djgentelella-0.5.0.dist-info → djgentelella-0.5.2.dist-info}/METADATA +1 -1
  39. {djgentelella-0.5.0.dist-info → djgentelella-0.5.2.dist-info}/RECORD +43 -37
  40. {djgentelella-0.5.0.dist-info → djgentelella-0.5.2.dist-info}/AUTHORS +0 -0
  41. {djgentelella-0.5.0.dist-info → djgentelella-0.5.2.dist-info}/LICENSE.txt +0 -0
  42. {djgentelella-0.5.0.dist-info → djgentelella-0.5.2.dist-info}/WHEEL +0 -0
  43. {djgentelella-0.5.0.dist-info → djgentelella-0.5.2.dist-info}/top_level.txt +0 -0
djgentelella/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = '0.5.0'
1
+ __version__ = '0.5.2'
2
2
 
3
3
  if __name__ == '__main__':
4
4
  print(__version__)
djgentelella/admin.py CHANGED
@@ -5,7 +5,9 @@ from djgentelella.models import MenuItem, Help, GentelellaSettings, Notification
5
5
  ChunkedUpload, Trash
6
6
  from djgentelella.models import PermissionsCategoryManagement
7
7
  from djgentelella.utils import clean_cache
8
-
8
+ from django.contrib.admin.models import LogEntry
9
+ from djgentelella.history.utils import ACTIONS
10
+ from django.utils.translation import gettext_lazy as _
9
11
 
10
12
  class MenuAdmin(admin.ModelAdmin):
11
13
  filter_horizontal = ['permission']
@@ -38,6 +40,36 @@ class TrashAdmin(admin.ModelAdmin):
38
40
  ordering = ("-created_at",)
39
41
  search_fields = ("id",)
40
42
 
43
+
44
+ class ActionFlagFilter(admin.SimpleListFilter):
45
+ title = _("Action")
46
+ parameter_name = "action_flag"
47
+
48
+ def lookups(self, request, model_admin):
49
+ return [(k, str(v)) for k, v in ACTIONS.items()]
50
+
51
+ def queryset(self, request, queryset):
52
+ val = self.value()
53
+ if not val:
54
+ return queryset
55
+ try:
56
+ return queryset.filter(action_flag=int(val))
57
+ except ValueError:
58
+ return queryset.none()
59
+
60
+ class LogEntryAdmin(admin.ModelAdmin):
61
+ verbose_name = _("History")
62
+ verbose_name_plural = _("History")
63
+ list_display = ("id", "action_time", "user", "content_type", "object_id", "object_repr", "action_label", "change_message")
64
+ search_fields = ("content_type__app_label", "content_type__model", "object_id", "user__username")
65
+ list_filter = (
66
+ ActionFlagFilter,
67
+ )
68
+ def action_label(self, obj):
69
+ return ACTIONS.get(obj.action_flag, obj.get_action_flag_display() or obj.action_flag)
70
+ action_label.short_description = _("Action")
71
+
72
+
41
73
  admin.site.register(UserSignatureConfig, UserSignatureConfigAdmin)
42
74
  admin.site.register(ChunkedUpload, ChunkedUploadAdmin)
43
75
  admin.site.register(MenuItem, MenuAdmin)
@@ -46,3 +78,4 @@ admin.site.register(PermissionsCategoryManagement)
46
78
  admin.site.register(GentelellaSettings, GentelellaSettingsAdmin)
47
79
  admin.site.register(Notification, NotificationAdmin)
48
80
  admin.site.register(Trash, TrashAdmin)
81
+ admin.site.register(LogEntry, LogEntryAdmin)
@@ -1,49 +1,26 @@
1
- from django.utils.translation import gettext_lazy as _
2
1
  from django.contrib.auth import get_user_model
3
2
  from django.db import models
3
+ from django.utils.translation import gettext_lazy as _
4
4
 
5
- FORMATS_DATE = [
6
- ("dd/MM/yyyy hh:mm:ss a", "dd/MM/yyyy hh:mm:ss a"),
7
- ("yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss"),
8
- ("MM/dd/yyyy hh:mm:ss a", "MM/dd/yyyy hh:mm:ss a"),
9
- ("dd-MM-yyyy", "dd-MM-yyyy"),
10
- ]
5
+ FORMATS_DATE = [("dd/MM/yyyy hh:mm:ss a", "dd/MM/yyyy hh:mm:ss a"),
6
+ ("yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm:ss"),
7
+ ("MM/dd/yyyy hh:mm:ss a", "MM/dd/yyyy hh:mm:ss a"),
8
+ ("dd-MM-yyyy", "dd-MM-yyyy"), ]
11
9
 
12
- FONT_ALIGNMENT = (
13
- ('NONE', _('None')),
14
- ('RIGHT', _('Right')),
15
- ('LEFT', _('Left')),
16
- ('TOP', _('Top')),
17
- ('BOTTOM', _('Bottom')),
18
- )
10
+ FONT_ALIGNMENT = (('NONE', _('None')), ('RIGHT', _('Right')), ('LEFT', _('Left')),
11
+ ('TOP', _('Top')), ('BOTTOM', _('Bottom')),)
19
12
 
20
13
 
21
14
  def get_signature_default():
22
- return {
23
- "backgroundColor": "transparent",
24
- "cAdESLevel": "LTA",
25
- "contact": "",
26
- "country": "CR",
27
- "dateFormat": "dd/MM/yyyy hh\:mm\:ss a",
28
- "defaultSignMessage": "Esta es una representación gráfica únicamente,\nverifique la validez de la firma.",
29
- "font": "Nimbus Sans Regular",
30
- "fontAlignment": "None",
31
- "fontColor": "000000",
32
- "fontSize": "7",
33
- "image": "",
34
- "language": "es",
35
- "pAdESLevel": "LTA",
36
- "place": "",
37
- "portNumber": "3516",
38
- "reason": "",
39
- "signHeight": "33",
40
- "signWidth": "133",
41
- "signX": "40",
42
- "signY": "60",
43
- "xAdESLevel": "LTA",
44
- "isVisibleSignature": False,
45
- "hideSignatureAdvice": False,
46
- }
15
+ return {"backgroundColor": "transparent", "cAdESLevel": "LTA", "contact": "",
16
+ "country": "CR", "dateFormat": "dd/MM/yyyy hh:mm:ss a",
17
+ "defaultSignMessage": "Esta es una representación gráfica únicamente,\nverifique la validez de la firma.",
18
+ "font": "Nimbus Sans Regular", "fontAlignment": "None",
19
+ "fontColor": "000000",
20
+ "fontSize": "7", "image": "", "language": "es", "pAdESLevel": "LTA",
21
+ "place": "", "portNumber": "3516", "reason": "", "signHeight": "33",
22
+ "signWidth": "133", "signX": "40", "signY": "60", "xAdESLevel": "LTA",
23
+ "isVisibleSignature": False, "hideSignatureAdvice": False, }
47
24
 
48
25
 
49
26
  class UserSignatureConfig(models.Model):
@@ -0,0 +1,142 @@
1
+ from djgentelella.objectmanagement import AuthAllPermBaseObjectManagement
2
+ from django.utils.translation import gettext_lazy as _
3
+ from djgentelella.history.utils import add_log
4
+ from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION
5
+ from djgentelella.history.serializers import HistoryDataTableSerializer
6
+ from djgentelella.history.filterset import HistoryFilterSet
7
+ from rest_framework.authentication import SessionAuthentication
8
+ from rest_framework.filters import SearchFilter, OrderingFilter
9
+ from rest_framework.pagination import LimitOffsetPagination
10
+ from django_filters.rest_framework import DjangoFilterBackend
11
+ from rest_framework.response import Response
12
+ from django.conf import settings
13
+ from django.db.models import Q
14
+ from django.contrib.contenttypes.models import ContentType
15
+
16
+
17
+
18
+ class BaseViewSetWithLogs(AuthAllPermBaseObjectManagement):
19
+
20
+ def perform_create(self, serializer):
21
+ super().perform_create(serializer)
22
+ new_instance = serializer.instance
23
+
24
+ add_log(
25
+ self.request.user,
26
+ new_instance,
27
+ ADDITION,
28
+ new_instance._meta.verbose_name.title().lower(),
29
+ [],
30
+ change_message=_("Created"),
31
+ )
32
+
33
+ def perform_update(self, serializer):
34
+ # get the instance before the update
35
+ instance = self.get_object()
36
+ old_values = {
37
+ field: getattr(instance, field)
38
+ for field in serializer.validated_data.keys()
39
+ }
40
+
41
+ super().perform_update(serializer)
42
+
43
+ new_instance = serializer.instance
44
+ # get changed fields
45
+ changed_fields = []
46
+
47
+ for field in serializer.validated_data.keys():
48
+ old_value = old_values.get(field)
49
+ new_value = getattr(new_instance, field)
50
+ if old_value != new_value:
51
+ changed_fields.append(field)
52
+
53
+ add_log(
54
+ self.request.user,
55
+ new_instance,
56
+ CHANGE,
57
+ new_instance._meta.verbose_name.title().lower(),
58
+ changed_data=changed_fields,
59
+ change_message=_("Updated"),
60
+ )
61
+
62
+ def perform_destroy(self, instance):
63
+ instance = self.get_object()
64
+ if instance._meta.verbose_name.title() in self.models_log:
65
+ add_log(
66
+ self.request.user,
67
+ instance,
68
+ DELETION,
69
+ instance._meta.verbose_name.title().lower(),
70
+ change_message=_("Deleted"),
71
+ )
72
+
73
+ super().perform_destroy(instance)
74
+
75
+
76
+ class HistoryViewSet(AuthAllPermBaseObjectManagement):
77
+ authentication_classes = [SessionAuthentication]
78
+ serializer_class = HistoryDataTableSerializer
79
+ queryset = LogEntry.objects.all()
80
+ pagination_class = LimitOffsetPagination
81
+ filter_backends = (DjangoFilterBackend, SearchFilter, OrderingFilter)
82
+ search_fields = ["object_repr"]
83
+ filterset_class = HistoryFilterSet
84
+ ordering_fields = ["-action_time"]
85
+ ordering = ("-action_time",)
86
+ perms = {"list": ["admin.view_logentry"]}
87
+
88
+ def get_queryset(self):
89
+ queryset = self.queryset
90
+
91
+ # check allowed models in settings
92
+ allowed = getattr(settings, "GT_HISTORY_ALLOWED_MODELS", None)
93
+
94
+ if allowed:
95
+ allowed_ctypes = self.contenttypes_from_settings(allowed)
96
+
97
+ if not allowed_ctypes.exists():
98
+ return queryset.none()
99
+
100
+ queryset = queryset.filter(content_type__in=allowed_ctypes).distinct()
101
+
102
+
103
+ # check contenttype param in form
104
+ ctypes_param = self.request.GET.get("contenttype")
105
+ if ctypes_param and ctypes_param in allowed:
106
+
107
+ ctypes_qs = self.contenttypes_from_settings([ctypes_param])
108
+
109
+ if not ctypes_qs.exists():
110
+ return queryset.none()
111
+
112
+ queryset = queryset.filter(content_type__in=ctypes_qs).distinct()
113
+
114
+ # default values
115
+ return queryset
116
+
117
+ def contenttypes_from_settings(self, entries):
118
+ q = Q()
119
+ for item in entries:
120
+ if isinstance(item, str) and "." in item:
121
+ app_label, model_name = item.split(".", 1)
122
+ app_label = app_label.strip()
123
+ model_key = model_name.strip().lower()
124
+ q |= Q(app_label=app_label, model=model_key)
125
+
126
+ if not q:
127
+ return ContentType.objects.none()
128
+ return ContentType.objects.filter(q)
129
+
130
+
131
+ def list(self, request, *args, **kwargs):
132
+ queryset = self.filter_queryset(self.get_queryset())
133
+ page = self.paginate_queryset(queryset)
134
+ data = page if page is not None else queryset
135
+
136
+ response = {
137
+ "data": data,
138
+ "recordsTotal": LogEntry.objects.count(),
139
+ "recordsFiltered": queryset.count(),
140
+ "draw": self.request.GET.get("draw", 1),
141
+ }
142
+ return Response(self.get_serializer(response).data)
@@ -0,0 +1,23 @@
1
+ from django.contrib.admin.models import LogEntry
2
+ from django_filters.rest_framework import FilterSet, ChoiceFilter
3
+ from django_filters import DateTimeFromToRangeFilter
4
+ from djgentelella.fields.drfdatetime import DateTimeRangeTextWidget
5
+ from djgentelella.history.utils import ACTIONS
6
+
7
+ class HistoryFilterSet(FilterSet):
8
+ action_time = DateTimeFromToRangeFilter(
9
+ widget=DateTimeRangeTextWidget(attrs={"placeholder": "DD/MM/YYYY/"})
10
+ )
11
+
12
+ action_flag = ChoiceFilter(
13
+ field_name="action_flag",
14
+ choices=[(k, str(v)) for k, v in ACTIONS.items()], # added 4 y 5
15
+ )
16
+
17
+ class Meta:
18
+ model = LogEntry
19
+ fields = {
20
+ "object_repr": ["icontains"],
21
+ "change_message": ["icontains"],
22
+ "user": ["exact"],
23
+ }
@@ -0,0 +1,50 @@
1
+ from django.contrib.admin.models import LogEntry
2
+ from django.contrib.contenttypes.models import ContentType
3
+ from django.utils.translation import gettext_lazy as _
4
+ from rest_framework import serializers
5
+ from djgentelella.serializers import GTDateField, GTDateTimeField
6
+
7
+
8
+
9
+ class HistorySerializer(serializers.ModelSerializer):
10
+ user = serializers.SerializerMethodField()
11
+ action_flag = serializers.SerializerMethodField()
12
+ action_time = GTDateTimeField()
13
+ change_message = serializers.SerializerMethodField()
14
+ actions = serializers.SerializerMethodField()
15
+
16
+ def get_user(self, obj):
17
+ if not obj or not obj.user:
18
+ return _("No user found")
19
+ name = obj.user.get_full_name()
20
+ return name or obj.user.username
21
+
22
+ def get_action_flag(self, obj):
23
+ if obj.action_flag == 4:
24
+ return _("Hard deleted")
25
+ elif obj.action_flag == 5:
26
+ return _("Restored")
27
+
28
+ return obj.get_action_flag_display()
29
+
30
+ def get_change_message(self, obj):
31
+ return obj.change_message
32
+
33
+ def get_actions(self, obj):
34
+ return {
35
+ "create": False,
36
+ "update": False,
37
+ "destroy": False,
38
+ }
39
+
40
+ class Meta:
41
+ model = LogEntry
42
+ fields = "__all__"
43
+
44
+
45
+ class HistoryDataTableSerializer(serializers.Serializer):
46
+ data = serializers.ListField(child=HistorySerializer(), required=True)
47
+ draw = serializers.IntegerField(required=True)
48
+ recordsFiltered = serializers.IntegerField(required=True)
49
+ recordsTotal = serializers.IntegerField(required=True)
50
+
@@ -0,0 +1,70 @@
1
+ from django.utils.translation import gettext_lazy as _
2
+ from django.contrib.admin.models import LogEntry, ADDITION, CHANGE, DELETION
3
+ from django.contrib.contenttypes.models import ContentType
4
+
5
+ HARD_DELETION = 4
6
+ RESTORE = 5
7
+
8
+ ACTIONS = {
9
+ ADDITION: _("created"),
10
+ CHANGE: _("updated"),
11
+ DELETION: _("deleted"),
12
+ HARD_DELETION: _("hard deleted"),
13
+ RESTORE: _("restored"),
14
+ }
15
+
16
+
17
+ def add_log(
18
+ user,
19
+ object,
20
+ action_flag,
21
+ model_name=None,
22
+ changed_data=None,
23
+ object_repr="",
24
+ change_message="",
25
+ content_type=None,
26
+ ):
27
+ if content_type is None:
28
+ content_type = ContentType.objects.get_for_model(object)
29
+
30
+ if model_name is None:
31
+ model_name = object._meta.verbose_name
32
+
33
+ if not isinstance(action_flag, int):
34
+ raise ValueError("action_flag must be an integer")
35
+
36
+ action_label = ACTIONS.get(action_flag, str(action_flag))
37
+
38
+ if not object_repr:
39
+ object_repr = _("An object of model %(model)s has been %(action)s") % {
40
+ "model": _(str(model_name).capitalize()),
41
+ "action": action_label,
42
+ }
43
+
44
+ changed_data = changed_data or []
45
+
46
+ if change_message:
47
+ if action_flag != DELETION and changed_data:
48
+ verbose_changes = [object._meta.get_field(f).verbose_name for f in
49
+ changed_data]
50
+
51
+ change_message = _("%(msg)s. Fields: %(fields)s") % {
52
+ "msg": change_message,
53
+ "fields": ", ".join(verbose_changes),
54
+ }
55
+ else: # delete, restore, hard delete
56
+ change_message = _("The record %(obj)s of model %(model)s has been %(action)s") % {
57
+ "obj": str(object),
58
+ "model": _(model_name),
59
+ "action": action_label,
60
+ }
61
+
62
+ LogEntry.objects.log_action(
63
+ user_id=user.id,
64
+ content_type_id=content_type.id,
65
+ object_id=object.pk,
66
+ object_repr=object_repr,
67
+ action_flag=action_flag,
68
+ change_message=change_message,
69
+ )
70
+
@@ -673,6 +673,7 @@ msgstr "El registro fue restaurado con éxito."
673
673
 
674
674
  msgid "The registry could not be restored."
675
675
  msgstr "No se pudo restaurar el registro."
676
+
676
677
  msgid "Signature image"
677
678
  msgstr "Imagen de firma"
678
679
 
@@ -683,3 +684,40 @@ msgid "Image signature"
683
684
  msgstr "Imagen de firma"
684
685
  msgid "Expand"
685
686
  msgstr "Expandir"
687
+
688
+ # history
689
+ msgid "Restoration"
690
+ msgstr "Restaurado"
691
+
692
+ msgid "deleted"
693
+ msgstr "eliminado"
694
+
695
+ msgid "Hard deleted"
696
+ msgstr "Eliminación permanente"
697
+
698
+ msgid "History"
699
+ msgstr "Historial"
700
+
701
+ msgid "General"
702
+ msgstr "General"
703
+
704
+ msgid "restored"
705
+ msgstr "restaurado"
706
+
707
+ msgid "Restored"
708
+ msgstr "Restaurado"
709
+
710
+ msgid "hard deleted"
711
+ msgstr "eliminado permanentemente"
712
+
713
+ msgid "%(msg)s. Fields: %(fields)s"
714
+ msgstr "%(msg)s. Campos: %(fields)s"
715
+
716
+ msgid "The record %(obj)s of model %(model)s has been %(action)s"
717
+ msgstr "El registro %(obj)s del modelo %(model)s ha sido %(action)s"
718
+
719
+ msgid "An object of model %(model)s has been %(action)s"
720
+ msgstr "Un objeto del modelo %(model)s ha sido %(action)s"
721
+
722
+ msgid "%(obj)s in trash"
723
+ msgstr "%(obj)s en papelera"
@@ -222,3 +222,40 @@ msgstr "El documento no está firmado digitalmente. Por favor, firme el document
222
222
 
223
223
  msgid "The document was saved"
224
224
  msgstr "El documento se ha guardado"
225
+
226
+ # history
227
+ msgid "Restoration"
228
+ msgstr "Restaurado"
229
+
230
+ msgid "deleted"
231
+ msgstr "eliminado"
232
+
233
+ msgid "Hard deleted"
234
+ msgstr "Eliminación permanente"
235
+
236
+ msgid "History"
237
+ msgstr "Historial"
238
+
239
+ msgid "General"
240
+ msgstr "General"
241
+
242
+ msgid "restored"
243
+ msgstr "restaurado"
244
+
245
+ msgid "Restored"
246
+ msgstr "Restaurado"
247
+
248
+ msgid "hard deleted"
249
+ msgstr "eliminado permanentemente"
250
+
251
+ msgid "%(msg)s. Fields: %(fields)s"
252
+ msgstr "%(msg)s. Campos: %(fields)s"
253
+
254
+ msgid "The record %(obj)s of model %(model)s has been %(action)s"
255
+ msgstr "El registro %(obj)s del modelo %(model)s ha sido %(action)s"
256
+
257
+ msgid "An object of model %(model)s has been %(action)s"
258
+ msgstr "Un objeto del modelo %(model)s ha sido %(action)s"
259
+
260
+ msgid "%(obj)s in trash"
261
+ msgstr "%(obj)s en papelera"
@@ -0,0 +1,18 @@
1
+ # Generated by Django 5.2.5 on 2025-08-29 23:46
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('djgentelella', '0016_trash_created_at'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='chunkedupload',
15
+ name='status',
16
+ field=models.PositiveSmallIntegerField(choices=[(1, 'Uploading'), (2, 'Complete')], default=1),
17
+ ),
18
+ ]
@@ -0,0 +1,18 @@
1
+ # Generated by Django 5.2.5 on 2025-08-29 23:55
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('djgentelella', '0017_alter_chunkedupload_status'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='chunkedupload',
15
+ name='status',
16
+ field=models.PositiveSmallIntegerField(choices=[(1, 'Subiendo'), (2, 'Completo')], default=1),
17
+ ),
18
+ ]
djgentelella/models.py CHANGED
@@ -10,6 +10,7 @@ from django.contrib.contenttypes.fields import GenericForeignKey
10
10
  from .models_manager import ObjectManager, AllObjectsManager, \
11
11
  DeletedObjectsManager
12
12
 
13
+ from djgentelella.history.utils import add_log, ADDITION
13
14
 
14
15
  class GentelellaSettings(models.Model):
15
16
  """
@@ -161,7 +162,7 @@ class Trash(models.Model):
161
162
  verbose_name_plural = _("Trash")
162
163
 
163
164
  def __str__(self):
164
- return _("Registration in trash: %(obj)s") % {"obj": self.object_repr}
165
+ return _("%(obj)s in trash") % {"obj": self.object_repr}
165
166
 
166
167
  def restore(self, user=None):
167
168
  obj = self.content_object
@@ -206,7 +207,7 @@ class DeletedWithTrash(models.Model):
206
207
  self.save(update_fields=["is_deleted"])
207
208
 
208
209
  # create trash instance
209
- Trash.objects.get_or_create(
210
+ trash = Trash.objects.get_or_create(
210
211
  content_type=ContentType.objects.get_for_model(self.__class__),
211
212
  object_id=self.pk,
212
213
  defaults={