|
1 | | -from auditlog.context import set_actor |
2 | | -from auditlog.signals import accessed |
3 | | -from rest_framework import mixins |
4 | | - |
5 | | - |
6 | | -class LogListAccessMixin(mixins.ListModelMixin): |
7 | | - """ |
8 | | - Mixin to log access to each object in a list view queryset, specifically |
9 | | - handling paginated results. |
10 | | -
|
11 | | - This mixin extends `ListModelMixin` to log access events for each object |
12 | | - retrieved in a list view, taking pagination into account. It overrides |
13 | | - `paginate_queryset` to ensure that access logs are written for the |
14 | | - objects on the current page. |
15 | | -
|
16 | | - Example Usage: |
17 | | -
|
18 | | - ```python |
19 | | - from rest_framework import generics |
20 | | - from .models import MyModel |
21 | | - from .serializers import MyModelSerializer |
22 | | -
|
23 | | -
|
24 | | - class MyModelListView(LogListAccessMixin, generics.ListAPIView): |
25 | | - queryset = MyModel.objects.all() |
26 | | - serializer_class = MyModelSerializer |
27 | | - ``` |
28 | | -
|
29 | | - Attributes: |
30 | | - accessed (Signal): A Django signal that is sent for each accessed object. |
31 | | -
|
32 | | - Methods: |
33 | | - paginate_queryset(self, queryset): |
34 | | - Overrides the `paginate_queryset` method to log access events for |
35 | | - objects on the current page. |
36 | | - _write_audit_access_log_of_paginated_objects(self, queryset): |
37 | | - Writes access log to audit log of each instance in the provided queryset. |
38 | | -
|
39 | | - Returns: |
40 | | - QuerySet: The paginated queryset retrieved by the parent's |
41 | | - `paginate_queryset` method, or the original queryset if |
42 | | - pagination is disabled. |
43 | | - """ |
44 | | - |
45 | | - def _write_audit_access_log_of_paginated_objects(self, queryset): |
46 | | - """ |
47 | | - Writes access log to audit log of each instance in the paginated queryset. |
48 | | -
|
49 | | - This private method iterates through the provided queryset and sends |
50 | | - the `accessed` signal for each object, logging the access event. |
51 | | -
|
52 | | - Args: |
53 | | - queryset: The paginated queryset (or the original queryset if |
54 | | - pagination is disabled) to log access events for. |
55 | | - """ |
56 | | - user = self.request.user |
57 | | - with set_actor(user): |
58 | | - for obj in queryset: |
59 | | - accessed.send(sender=obj.__class__, instance=obj) |
60 | | - |
61 | | - def paginate_queryset(self, queryset): |
62 | | - """ |
63 | | - Paginates the queryset and logs access for each object on the current page. |
64 | | -
|
65 | | - This method overrides the default `paginate_queryset` method to first |
66 | | - paginate the queryset and then log access events for each object in the |
67 | | - resulting page (or the original queryset if pagination is disabled). |
68 | | -
|
69 | | - Args: |
70 | | - queryset: The queryset to paginate. |
71 | | -
|
72 | | - Returns: |
73 | | - QuerySet: The paginated queryset, or the original queryset if |
74 | | - pagination is disabled. |
75 | | - """ |
76 | | - page = super().paginate_queryset(queryset) |
77 | | - |
78 | | - logged_objects = page if page is not None else queryset |
79 | | - self._write_audit_access_log_of_paginated_objects(logged_objects) |
80 | | - |
81 | | - return page |
82 | | - |
83 | | - |
84 | 1 | class SaveAfterPostGenerationMixin: |
85 | 2 | """ |
86 | 3 | Mixin for saving Django model instances after post-generation hooks. |
|
0 commit comments