maquinaweb-shared-auth 0.2.30__tar.gz → 0.2.32__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.

Potentially problematic release.


This version of maquinaweb-shared-auth might be problematic. Click here for more details.

Files changed (28) hide show
  1. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/PKG-INFO +2 -2
  2. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/README.md +1 -1
  3. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/maquinaweb_shared_auth.egg-info/PKG-INFO +2 -2
  4. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/pyproject.toml +1 -1
  5. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/managers.py +16 -85
  6. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/mixins.py +0 -1
  7. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/models.py +2 -2
  8. maquinaweb_shared_auth-0.2.32/shared_auth/serializers.py +412 -0
  9. maquinaweb_shared_auth-0.2.30/shared_auth/serializers.py +0 -232
  10. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/maquinaweb_shared_auth.egg-info/SOURCES.txt +0 -0
  11. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/maquinaweb_shared_auth.egg-info/dependency_links.txt +0 -0
  12. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/maquinaweb_shared_auth.egg-info/requires.txt +0 -0
  13. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/maquinaweb_shared_auth.egg-info/top_level.txt +0 -0
  14. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/setup.cfg +0 -0
  15. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/setup.py +0 -0
  16. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/__init__.py +0 -0
  17. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/app.py +0 -0
  18. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/authentication.py +0 -0
  19. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/conf.py +0 -0
  20. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/decorators.py +0 -0
  21. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/exceptions.py +0 -0
  22. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/fields.py +0 -0
  23. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/middleware.py +0 -0
  24. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/permissions.py +0 -0
  25. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/router.py +0 -0
  26. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/storage_backend.py +0 -0
  27. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/urls.py +0 -0
  28. {maquinaweb_shared_auth-0.2.30 → maquinaweb_shared_auth-0.2.32}/shared_auth/views.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maquinaweb-shared-auth
3
- Version: 0.2.30
3
+ Version: 0.2.32
4
4
  Summary: Models read-only para autenticação compartilhada entre projetos Django.
5
5
  Author-email: Seu Nome <seuemail@dominio.com>
6
6
  License: MIT
@@ -743,7 +743,7 @@ SharedOrganization.objects.main_organizations() # QuerySet (is_branch=False)
743
743
  SharedOrganization.objects.by_cnpj('12.345.678/0001-90') # Org | None
744
744
  ```
745
745
 
746
- #### SharedUserManager
746
+ #### UserManager
747
747
 
748
748
  ```python
749
749
  from shared_auth.models import User
@@ -721,7 +721,7 @@ SharedOrganization.objects.main_organizations() # QuerySet (is_branch=False)
721
721
  SharedOrganization.objects.by_cnpj('12.345.678/0001-90') # Org | None
722
722
  ```
723
723
 
724
- #### SharedUserManager
724
+ #### UserManager
725
725
 
726
726
  ```python
727
727
  from shared_auth.models import User
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maquinaweb-shared-auth
3
- Version: 0.2.30
3
+ Version: 0.2.32
4
4
  Summary: Models read-only para autenticação compartilhada entre projetos Django.
5
5
  Author-email: Seu Nome <seuemail@dominio.com>
6
6
  License: MIT
@@ -743,7 +743,7 @@ SharedOrganization.objects.main_organizations() # QuerySet (is_branch=False)
743
743
  SharedOrganization.objects.by_cnpj('12.345.678/0001-90') # Org | None
744
744
  ```
745
745
 
746
- #### SharedUserManager
746
+ #### UserManager
747
747
 
748
748
  ```python
749
749
  from shared_auth.models import User
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "maquinaweb-shared-auth"
7
- version = "0.2.30"
7
+ version = "0.2.32"
8
8
  description = "Models read-only para autenticação compartilhada entre projetos Django."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13"
@@ -45,8 +45,8 @@ class SharedOrganizationManager(models.Manager):
45
45
  return self.filter(cnpj__contains=clean_cnpj).first()
46
46
 
47
47
 
48
- class SharedUserManager(UserManager):
49
- """Manager para SharedUser"""
48
+ class UserManager(UserManager):
49
+ """Manager para User"""
50
50
 
51
51
  def get_or_fail(self, user_id):
52
52
  """Busca usuário ou lança exceção"""
@@ -89,38 +89,16 @@ class OrganizationQuerySetMixin:
89
89
 
90
90
  def with_organization_data(self):
91
91
  """
92
- Pré-carrega dados de organizações (evita N+1 queries)
93
-
94
- Faz uma única query bulk para buscar todas as organizações necessárias
95
- e cacheia nos objetos usando _cached_organization.
96
-
97
- IMPORTANTE: Este método força a avaliação do QuerySet e aplica cache.
98
- Para manter a chain de QuerySet, chame este método por último.
99
-
100
- Usage:
101
- # Sem otimização (N+1 queries)
102
- rascunhos = Rascunho.objects.all()
103
- for r in rascunhos:
104
- print(r.organization.name) # Query individual para cada
105
-
106
- # Com otimização (2 queries total)
107
- rascunhos = Rascunho.objects.all().with_organization_data()
108
- for r in rascunhos:
109
- print(r.organization.name) # Usa cache, sem queries extras
92
+ Pré-carrega dados de organizações (evita N+1)
110
93
 
111
94
  Returns:
112
- Self (QuerySet) com _prefetch_done=True e objetos cacheados
95
+ Lista de objetos com _cached_organization
113
96
  """
114
- # Marcar que o prefetch foi feito
115
- self._prefetch_done = True
116
-
117
- # Forçar avaliação do queryset
118
- objects = list(self)
97
+ objects = list(self.all())
98
+ from .models import SharedOrganization
119
99
 
120
100
  if not objects:
121
- return self
122
-
123
- from .models import SharedOrganization
101
+ return objects
124
102
 
125
103
  # Coletar IDs únicos
126
104
  org_ids = set(obj.organization_id for obj in objects)
@@ -134,10 +112,7 @@ class OrganizationQuerySetMixin:
134
112
  for obj in objects:
135
113
  obj._cached_organization = organizations.get(obj.organization_id)
136
114
 
137
- # Armazenar os objetos cacheados no queryset
138
- self._result_cache = objects
139
-
140
- return self
115
+ return objects
141
116
 
142
117
 
143
118
  class UserQuerySetMixin:
@@ -153,27 +128,14 @@ class UserQuerySetMixin:
153
128
 
154
129
  def with_user_data(self):
155
130
  """
156
- Pré-carrega dados de usuários (evita N+1 queries)
157
-
158
- Usage:
159
- # Com otimização (2 queries total)
160
- rascunhos = Rascunho.objects.all().with_user_data()
161
- for r in rascunhos:
162
- print(r.user.email) # Usa cache, sem queries extras
163
-
164
- Returns:
165
- Self (QuerySet) com objetos cacheados
131
+ Pré-carrega dados de usuários (evita N+1)
166
132
  """
167
133
  from .models import User
168
134
 
169
- # Marcar que o prefetch foi feito
170
- self._prefetch_done = True
171
-
172
- # Forçar avaliação do queryset
173
- objects = list(self)
135
+ objects = list(self.all())
174
136
 
175
137
  if not objects:
176
- return self
138
+ return objects
177
139
 
178
140
  user_ids = set(obj.user_id for obj in objects)
179
141
 
@@ -182,10 +144,7 @@ class UserQuerySetMixin:
182
144
  for obj in objects:
183
145
  obj._cached_user = users.get(obj.user_id)
184
146
 
185
- # Armazenar os objetos cacheados no queryset
186
- self._result_cache = objects
187
-
188
- return self
147
+ return objects
189
148
 
190
149
 
191
150
  class OrganizationUserQuerySetMixin(OrganizationQuerySetMixin, UserQuerySetMixin):
@@ -193,39 +152,14 @@ class OrganizationUserQuerySetMixin(OrganizationQuerySetMixin, UserQuerySetMixin
193
152
 
194
153
  def with_auth_data(self):
195
154
  """
196
- Pré-carrega dados de organizações E usuários (evita N+1 queries)
197
-
198
- Faz apenas 3 queries no total, independente da quantidade de objetos:
199
- 1. Query dos objetos principais
200
- 2. Query bulk das organizações
201
- 3. Query bulk dos usuários
202
-
203
- Usage:
204
- # Sem otimização (1 + N + N queries)
205
- rascunhos = Rascunho.objects.all() # 1 query
206
- for r in rascunhos:
207
- print(r.organization.name) # N queries
208
- print(r.user.email) # N queries
209
-
210
- # Com otimização (3 queries total)
211
- rascunhos = Rascunho.objects.all().with_auth_data()
212
- for r in rascunhos:
213
- print(r.organization.name) # Cache
214
- print(r.user.email) # Cache
215
-
216
- Returns:
217
- Self (QuerySet) com objetos cacheados
155
+ Pré-carrega dados de organizações E usuários (evita N+1)
218
156
  """
219
157
  from .models import SharedOrganization, User
220
158
 
221
- # Marcar que o prefetch foi feito
222
- self._prefetch_done = True
223
-
224
- # Forçar avaliação do queryset
225
- objects = list(self)
159
+ objects = list(self.all())
226
160
 
227
161
  if not objects:
228
- return self
162
+ return objects
229
163
 
230
164
  # Coletar IDs
231
165
  org_ids = set(obj.organization_id for obj in objects)
@@ -243,10 +177,7 @@ class OrganizationUserQuerySetMixin(OrganizationQuerySetMixin, UserQuerySetMixin
243
177
  obj._cached_organization = organizations.get(obj.organization_id)
244
178
  obj._cached_user = users.get(obj.user_id)
245
179
 
246
- # Armazenar os objetos cacheados no queryset
247
- self._result_cache = objects
248
-
249
- return self
180
+ return objects
250
181
 
251
182
  def create_with_validation(self, organization_id, user_id, **kwargs):
252
183
  """
@@ -227,7 +227,6 @@ class LoggedOrganizationMixin(viewsets.ModelViewSet):
227
227
  return queryset.none()
228
228
 
229
229
  organization_id = self.get_organization_id()
230
-
231
230
  if hasattr(queryset.model, "organization_id"):
232
231
  return queryset.filter(organization_id=organization_id)
233
232
  elif hasattr(queryset.model, "organization"):
@@ -10,7 +10,7 @@ from django.db import models
10
10
 
11
11
  from .conf import MEMBER_TABLE, ORGANIZATION_TABLE, TOKEN_TABLE, USER_TABLE
12
12
  from .exceptions import OrganizationNotFoundError
13
- from .managers import SharedMemberManager, SharedOrganizationManager, SharedUserManager
13
+ from .managers import SharedMemberManager, SharedOrganizationManager, UserManager
14
14
  from .storage_backend import Storage
15
15
 
16
16
 
@@ -155,7 +155,7 @@ class User(AbstractUser):
155
155
  updatedat = models.DateTimeField()
156
156
  deleted_at = models.DateTimeField(null=True, blank=True)
157
157
 
158
- objects = SharedUserManager()
158
+ objects = UserManager()
159
159
 
160
160
  class Meta:
161
161
  managed = False
@@ -0,0 +1,412 @@
1
+ """
2
+ Serializers compartilhados para DRF
3
+
4
+ Separação de responsabilidades:
5
+ - CreateSerializerMixin: apenas para criação (seta IDs do request)
6
+ - SerializerMixin: listagem com dados aninhados + criação (compatibilidade com código existente)
7
+
8
+ Se quiser usar separadamente:
9
+ - Use apenas *CreateSerializerMixin para create
10
+ - Use apenas *SerializerMixin para listagem
11
+ - Ou herde ambos se precisar
12
+ """
13
+
14
+ from rest_framework import serializers
15
+
16
+ from .models import SharedOrganization, User
17
+
18
+
19
+ class OrganizationCreateSerializerMixin(serializers.ModelSerializer):
20
+ """
21
+ Mixin APENAS para criação.
22
+ Automaticamente seta organization_id no create a partir do request context.
23
+
24
+ Usage:
25
+ class RascunhoCreateSerializer(OrganizationCreateSerializerMixin, serializers.ModelSerializer):
26
+ class Meta:
27
+ model = Rascunho
28
+ fields = ['id', 'titulo', 'conteudo']
29
+ """
30
+
31
+ def create(self, validated_data):
32
+ """Automatically set organization_id from request context"""
33
+ if self.context.get("request") and hasattr(
34
+ self.context["request"], "organization_id"
35
+ ):
36
+ validated_data["organization_id"] = self.context["request"].organization_id
37
+ return super().create(validated_data)
38
+
39
+
40
+ class OrganizationSerializerMixin(serializers.ModelSerializer):
41
+ """
42
+ Mixin para serializers que incluem dados de organização como objeto aninhado
43
+ e automaticamente setam organization_id no create a partir do request context.
44
+
45
+ Retorna:
46
+ {
47
+ "id": 1,
48
+ "titulo": "Teste",
49
+ "organization": {
50
+ "id": 123,
51
+ "name": "Empresa XYZ",
52
+ "cnpj": "12.345.678/0001-90",
53
+ "email": "contato@xyz.com",
54
+ "is_active": true
55
+ }
56
+ }
57
+
58
+ Usage:
59
+ class RascunhoSerializer(OrganizationSerializerMixin, serializers.ModelSerializer):
60
+ class Meta:
61
+ model = Rascunho
62
+ fields = ['id', 'titulo', 'organization']
63
+
64
+ # Ou apenas para listagem (sem create):
65
+ class RascunhoListSerializer(OrganizationSerializerMixin, serializers.ModelSerializer):
66
+ class Meta:
67
+ model = Rascunho
68
+ fields = ['id', 'titulo', 'organization']
69
+
70
+ # Ou combinar com create:
71
+ class RascunhoFullSerializer(OrganizationSerializerMixin, OrganizationCreateSerializerMixin):
72
+ class Meta:
73
+ model = Rascunho
74
+ fields = ['id', 'titulo', 'organization']
75
+ """
76
+
77
+ organization = serializers.SerializerMethodField()
78
+
79
+ def get_organization(self, obj):
80
+ """Retorna dados da organização como objeto"""
81
+ try:
82
+ org = obj.organization
83
+ return {
84
+ "id": org.pk,
85
+ "name": org.name,
86
+ "fantasy_name": org.fantasy_name,
87
+ "image_organization": org.image_organization.url
88
+ if org.image_organization
89
+ else None,
90
+ "cnpj": org.cnpj,
91
+ "email": org.email,
92
+ "telephone": org.telephone,
93
+ "cellphone": org.cellphone,
94
+ "is_branch": org.is_branch,
95
+ "is_active": org.is_active(),
96
+ }
97
+ except Exception:
98
+ return None
99
+
100
+
101
+ class OrganizationListCreateSerializerMixin(
102
+ OrganizationSerializerMixin, OrganizationCreateSerializerMixin
103
+ ):
104
+ """
105
+ Mixin COMPLETO pronto para usar: listagem + criação.
106
+ Combina OrganizationSerializerMixin + OrganizationCreateSerializerMixin.
107
+
108
+ Usage:
109
+ class RascunhoSerializer(OrganizationListCreateSerializerMixin, serializers.ModelSerializer):
110
+ class Meta:
111
+ model = Rascunho
112
+ fields = ['id', 'titulo', 'organization']
113
+ """
114
+
115
+ pass
116
+
117
+
118
+ class OrganizationSerializer(serializers.ModelSerializer):
119
+ class Meta:
120
+ model = SharedOrganization
121
+ fields = "__all__"
122
+
123
+
124
+ class UserCreateSerializerMixin(serializers.ModelSerializer):
125
+ """
126
+ Mixin APENAS para criação.
127
+ Automaticamente seta user_id no create a partir do request context.
128
+
129
+ Usage:
130
+ class RascunhoCreateSerializer(UserCreateSerializerMixin, serializers.ModelSerializer):
131
+ class Meta:
132
+ model = Rascunho
133
+ fields = ['id', 'titulo', 'conteudo']
134
+ """
135
+
136
+ def create(self, validated_data):
137
+ """Automatically set user_id from request context"""
138
+ if self.context.get("request") and hasattr(self.context["request"], "user"):
139
+ validated_data["user_id"] = self.context["request"].user.id
140
+ return super().create(validated_data)
141
+
142
+
143
+ class UserSerializerMixin(serializers.ModelSerializer):
144
+ """
145
+ Mixin para serializers que incluem dados de usuário como objeto aninhado
146
+ e automaticamente setam user_id no create a partir do request context.
147
+
148
+ Retorna:
149
+ {
150
+ "id": 1,
151
+ "titulo": "Teste",
152
+ "user": {
153
+ "id": 456,
154
+ "username": "joao",
155
+ "email": "joao@xyz.com",
156
+ "full_name": "João Silva",
157
+ "is_active": true
158
+ }
159
+ }
160
+
161
+ Usage:
162
+ class RascunhoSerializer(UserSerializerMixin, serializers.ModelSerializer):
163
+ class Meta:
164
+ model = Rascunho
165
+ fields = ['id', 'titulo', 'user']
166
+
167
+ # Ou apenas para listagem (sem create):
168
+ class RascunhoListSerializer(UserSerializerMixin, serializers.ModelSerializer):
169
+ class Meta:
170
+ model = Rascunho
171
+ fields = ['id', 'titulo', 'user']
172
+
173
+ # Ou combinar com create:
174
+ class RascunhoFullSerializer(UserSerializerMixin, UserCreateSerializerMixin):
175
+ class Meta:
176
+ model = Rascunho
177
+ fields = ['id', 'titulo', 'user']
178
+ """
179
+
180
+ user = serializers.SerializerMethodField()
181
+
182
+ def get_user(self, obj):
183
+ """Retorna dados do usuário como objeto"""
184
+ try:
185
+ user: User = obj.user
186
+ return {
187
+ "id": user.pk,
188
+ "username": user.username,
189
+ "email": user.email,
190
+ "avatar": user.avatar.url if user.avatar else None,
191
+ "first_name": user.first_name,
192
+ "last_name": user.last_name,
193
+ "full_name": user.get_full_name(),
194
+ "is_active": user.is_active,
195
+ }
196
+ except Exception:
197
+ return None
198
+
199
+
200
+ class UserListCreateSerializerMixin(UserSerializerMixin, UserCreateSerializerMixin):
201
+ """
202
+ Mixin COMPLETO pronto para usar: listagem + criação.
203
+ Combina UserSerializerMixin + UserCreateSerializerMixin.
204
+
205
+ Usage:
206
+ class RascunhoSerializer(UserListCreateSerializerMixin, serializers.ModelSerializer):
207
+ class Meta:
208
+ model = Rascunho
209
+ fields = ['id', 'titulo', 'user']
210
+ """
211
+
212
+ pass
213
+
214
+
215
+ class UserSerializer(serializers.ModelSerializer):
216
+ class Meta:
217
+ model = User
218
+ fields = [
219
+ "id",
220
+ "username",
221
+ "first_name",
222
+ "last_name",
223
+ "email",
224
+ "is_active",
225
+ "is_staff",
226
+ "is_superuser",
227
+ "date_joined",
228
+ "last_login",
229
+ ]
230
+
231
+
232
+ class OrganizationUserCreateSerializerMixin(serializers.ModelSerializer):
233
+ """
234
+ Mixin APENAS para criação com organization + user.
235
+ Automaticamente seta organization_id e user_id no create a partir do request context.
236
+
237
+ Usage:
238
+ class RascunhoCreateSerializer(OrganizationUserCreateSerializerMixin, serializers.ModelSerializer):
239
+ class Meta:
240
+ model = Rascunho
241
+ fields = ['id', 'titulo', 'conteudo']
242
+ """
243
+
244
+ def create(self, validated_data):
245
+ """Automatically set both organization_id and user_id from request context"""
246
+ if self.context.get("request"):
247
+ request = self.context["request"]
248
+ if hasattr(request, "organization_id"):
249
+ validated_data["organization_id"] = request.organization_id
250
+ if hasattr(request, "user"):
251
+ validated_data["user_id"] = request.user.id
252
+ return super().create(validated_data)
253
+
254
+
255
+ class OrganizationUserSerializerMixin(OrganizationSerializerMixin, UserSerializerMixin):
256
+ """
257
+ Mixin combinado com organization e user como objetos aninhados
258
+ e automaticamente seta organization_id e user_id no create a partir do request context.
259
+
260
+ Retorna:
261
+ {
262
+ "id": 1,
263
+ "titulo": "Teste",
264
+ "organization": {
265
+ "id": 123,
266
+ "name": "Empresa XYZ",
267
+ ...
268
+ },
269
+ "user": {
270
+ "id": 456,
271
+ "username": "joao",
272
+ ...
273
+ }
274
+ }
275
+
276
+ Usage:
277
+ class RascunhoSerializer(OrganizationUserSerializerMixin, serializers.ModelSerializer):
278
+ class Meta:
279
+ model = Rascunho
280
+ fields = ['id', 'titulo', 'conteudo', 'organization', 'user']
281
+
282
+ # Ou apenas para listagem (sem create):
283
+ class RascunhoListSerializer(OrganizationUserSerializerMixin, serializers.ModelSerializer):
284
+ class Meta:
285
+ model = Rascunho
286
+ fields = ['id', 'titulo', 'organization', 'user']
287
+
288
+ # Ou combinar com create:
289
+ class RascunhoFullSerializer(OrganizationUserSerializerMixin, OrganizationUserCreateSerializerMixin):
290
+ class Meta:
291
+ model = Rascunho
292
+ fields = ['id', 'titulo', 'organization', 'user']
293
+ """
294
+
295
+ pass
296
+
297
+
298
+ class OrganizationUserListCreateSerializerMixin(
299
+ OrganizationUserSerializerMixin, OrganizationUserCreateSerializerMixin
300
+ ):
301
+ """
302
+ Mixin COMPLETO pronto para usar: listagem + criação com organization + user.
303
+ Combina OrganizationUserSerializerMixin + OrganizationUserCreateSerializerMixin.
304
+
305
+ Usage:
306
+ class RascunhoSerializer(OrganizationUserListCreateSerializerMixin, serializers.ModelSerializer):
307
+ class Meta:
308
+ model = Rascunho
309
+ fields = ['id', 'titulo', 'organization', 'user']
310
+ """
311
+
312
+ pass
313
+
314
+
315
+ class OrganizationSimpleSerializerMixin(serializers.ModelSerializer):
316
+ """
317
+ Versão simplificada que retorna apenas campos essenciais da organização
318
+ e automaticamente seta organization_id no create a partir do request context.
319
+
320
+ Usage:
321
+ # Para listagem:
322
+ class RascunhoListSerializer(OrganizationSimpleSerializerMixin, serializers.ModelSerializer):
323
+ class Meta:
324
+ model = Rascunho
325
+ fields = ['id', 'titulo', 'organization']
326
+
327
+ # Para criar com organization:
328
+ class RascunhoCreateSerializer(OrganizationSimpleSerializerMixin, OrganizationCreateSerializerMixin):
329
+ class Meta:
330
+ model = Rascunho
331
+ fields = ['id', 'titulo', 'organization']
332
+ """
333
+
334
+ organization = serializers.SerializerMethodField()
335
+
336
+ def get_organization(self, obj):
337
+ try:
338
+ org = obj.organization
339
+ return {
340
+ "id": org.pk,
341
+ "name": org.name,
342
+ "cnpj": org.cnpj,
343
+ }
344
+ except Exception:
345
+ return None
346
+
347
+
348
+ class OrganizationSimpleListCreateSerializerMixin(
349
+ OrganizationSimpleSerializerMixin, OrganizationCreateSerializerMixin
350
+ ):
351
+ """
352
+ Versão simplificada COMPLETA pronta para usar: listagem + criação.
353
+ Retorna apenas campos essenciais da organização.
354
+
355
+ Usage:
356
+ class RascunhoSerializer(OrganizationSimpleListCreateSerializerMixin, serializers.ModelSerializer):
357
+ class Meta:
358
+ model = Rascunho
359
+ fields = ['id', 'titulo', 'organization']
360
+ """
361
+
362
+ pass
363
+
364
+
365
+ class UserSimpleSerializerMixin(serializers.ModelSerializer):
366
+ """
367
+ Versão simplificada que retorna apenas campos essenciais do usuário
368
+ e automaticamente seta user_id no create a partir do request context.
369
+
370
+ Usage:
371
+ # Para listagem:
372
+ class RascunhoListSerializer(UserSimpleSerializerMixin, serializers.ModelSerializer):
373
+ class Meta:
374
+ model = Rascunho
375
+ fields = ['id', 'titulo', 'user']
376
+
377
+ # Para criar com user:
378
+ class RascunhoCreateSerializer(UserSimpleSerializerMixin, UserCreateSerializerMixin):
379
+ class Meta:
380
+ model = Rascunho
381
+ fields = ['id', 'titulo', 'user']
382
+ """
383
+
384
+ user = serializers.SerializerMethodField()
385
+
386
+ def get_user(self, obj):
387
+ try:
388
+ user = obj.user
389
+ return {
390
+ "id": user.pk,
391
+ "email": user.email,
392
+ "full_name": user.get_full_name(),
393
+ }
394
+ except Exception:
395
+ return None
396
+
397
+
398
+ class UserSimpleListCreateSerializerMixin(
399
+ UserSimpleSerializerMixin, UserCreateSerializerMixin
400
+ ):
401
+ """
402
+ Versão simplificada COMPLETA pronta para usar: listagem + criação.
403
+ Retorna apenas campos essenciais do usuário.
404
+
405
+ Usage:
406
+ class RascunhoSerializer(UserSimpleListCreateSerializerMixin, serializers.ModelSerializer):
407
+ class Meta:
408
+ model = Rascunho
409
+ fields = ['id', 'titulo', 'user']
410
+ """
411
+
412
+ pass
@@ -1,232 +0,0 @@
1
- """
2
- Serializers compartilhados para DRF
3
- """
4
-
5
- from rest_framework import serializers
6
-
7
- from .models import SharedOrganization, User
8
-
9
-
10
- class OrganizationSerializerMixin(serializers.ModelSerializer):
11
- """
12
- Mixin para serializers que incluem dados de organização como objeto aninhado
13
- e automaticamente setam organization_id no create a partir do request context.
14
-
15
- Retorna:
16
- {
17
- "id": 1,
18
- "titulo": "Teste",
19
- "organization": {
20
- "id": 123,
21
- "name": "Empresa XYZ",
22
- "cnpj": "12.345.678/0001-90",
23
- "email": "contato@xyz.com",
24
- "is_active": true
25
- }
26
- }
27
-
28
- Usage:
29
- class RascunhoSerializer(OrganizationSerializerMixin, serializers.ModelSerializer):
30
- class Meta:
31
- model = Rascunho
32
- fields = ['id', 'titulo', 'organization']
33
- """
34
-
35
- organization = serializers.SerializerMethodField()
36
-
37
- def get_organization(self, obj):
38
- """Retorna dados da organização como objeto"""
39
- try:
40
- org = obj.organization
41
- return {
42
- "id": org.pk,
43
- "name": org.name,
44
- "fantasy_name": org.fantasy_name,
45
- "image_organization": org.image_organization.url
46
- if org.image_organization
47
- else None,
48
- "cnpj": org.cnpj,
49
- "email": org.email,
50
- "telephone": org.telephone,
51
- "cellphone": org.cellphone,
52
- "is_branch": org.is_branch,
53
- "is_active": org.is_active(),
54
- }
55
- except Exception:
56
- return None
57
-
58
- def create(self, validated_data):
59
- """Automatically set organization_id from request context"""
60
- if self.context.get("request") and hasattr(
61
- self.context["request"], "organization_id"
62
- ):
63
- validated_data["organization_id"] = self.context["request"].organization_id
64
- return super().create(validated_data)
65
-
66
-
67
- class OrganizationSerializer(serializers.ModelSerializer):
68
- class Meta:
69
- model = SharedOrganization
70
- fields = "__all__"
71
-
72
-
73
- class UserSerializer(serializers.ModelSerializer):
74
- class Meta:
75
- model = User
76
- fields = [
77
- "id",
78
- "username",
79
- "first_name",
80
- "last_name",
81
- "email",
82
- "is_active",
83
- "is_staff",
84
- "is_superuser",
85
- "date_joined",
86
- "last_login",
87
- ]
88
-
89
-
90
- class UserSerializerMixin(serializers.ModelSerializer):
91
- """
92
- Mixin para serializers que incluem dados de usuário como objeto aninhado
93
- e automaticamente setam user_id no create a partir do request context.
94
-
95
- Retorna:
96
- {
97
- "id": 1,
98
- "titulo": "Teste",
99
- "user": {
100
- "id": 456,
101
- "username": "joao",
102
- "email": "joao@xyz.com",
103
- "full_name": "João Silva",
104
- "is_active": true
105
- }
106
- }
107
-
108
- Usage:
109
- class RascunhoSerializer(UserSerializerMixin, serializers.ModelSerializer):
110
- class Meta:
111
- model = Rascunho
112
- fields = ['id', 'titulo', 'user']
113
- """
114
-
115
- user = serializers.SerializerMethodField()
116
-
117
- def get_user(self, obj):
118
- """Retorna dados do usuário como objeto"""
119
- try:
120
- user: User = obj.user
121
- return {
122
- "id": user.pk,
123
- "username": user.username,
124
- "email": user.email,
125
- "avatar": user.avatar.url if user.avatar else None,
126
- "first_name": user.first_name,
127
- "last_name": user.last_name,
128
- "full_name": user.get_full_name(),
129
- "is_active": user.is_active,
130
- }
131
- except Exception:
132
- return None
133
-
134
- def create(self, validated_data):
135
- """Automatically set user_id from request context"""
136
- if self.context.get("request") and hasattr(self.context["request"], "user"):
137
- validated_data["user_id"] = self.context["request"].user.id
138
- return super().create(validated_data)
139
-
140
-
141
- class OrganizationUserSerializerMixin(OrganizationSerializerMixin, UserSerializerMixin):
142
- """
143
- Mixin combinado com organization e user como objetos aninhados
144
- e automaticamente seta organization_id e user_id no create a partir do request context.
145
-
146
- Retorna:
147
- {
148
- "id": 1,
149
- "titulo": "Teste",
150
- "organization": {
151
- "id": 123,
152
- "name": "Empresa XYZ",
153
- ...
154
- },
155
- "user": {
156
- "id": 456,
157
- "username": "joao",
158
- ...
159
- }
160
- }
161
-
162
- Usage:
163
- class RascunhoSerializer(OrganizationUserSerializerMixin, serializers.ModelSerializer):
164
- class Meta:
165
- model = Rascunho
166
- fields = ['id', 'titulo', 'conteudo', 'organization', 'user']
167
- """
168
-
169
- def create(self, validated_data):
170
- """Automatically set both organization_id and user_id from request context"""
171
- if self.context.get("request"):
172
- request = self.context["request"]
173
- if hasattr(request, "organization_id"):
174
- validated_data["organization_id"] = request.organization_id
175
- if hasattr(request, "user"):
176
- validated_data["user_id"] = request.user.id
177
- return super(UserSerializerMixin, self).create(validated_data)
178
-
179
-
180
- # Versões simplificadas (opcional)
181
- class OrganizationSimpleSerializerMixin(serializers.ModelSerializer):
182
- """
183
- Versão simplificada que retorna apenas campos essenciais da organização
184
- e automaticamente seta organization_id no create a partir do request context.
185
- """
186
-
187
- organization = serializers.SerializerMethodField()
188
-
189
- def get_organization(self, obj):
190
- try:
191
- org = obj.organization
192
- return {
193
- "id": org.pk,
194
- "name": org.name,
195
- "cnpj": org.cnpj,
196
- }
197
- except:
198
- return None
199
-
200
- def create(self, validated_data):
201
- """Automatically set organization_id from request context"""
202
- if self.context.get("request") and hasattr(
203
- self.context["request"], "organization_id"
204
- ):
205
- validated_data["organization_id"] = self.context["request"].organization_id
206
- return super().create(validated_data)
207
-
208
-
209
- class UserSimpleSerializerMixin(serializers.ModelSerializer):
210
- """
211
- Versão simplificada que retorna apenas campos essenciais do usuário
212
- e automaticamente seta user_id no create a partir do request context.
213
- """
214
-
215
- user = serializers.SerializerMethodField()
216
-
217
- def get_user(self, obj):
218
- try:
219
- user = obj.user
220
- return {
221
- "id": user.pk,
222
- "email": user.email,
223
- "full_name": user.get_full_name(),
224
- }
225
- except:
226
- return None
227
-
228
- def create(self, validated_data):
229
- """Automatically set user_id from request context"""
230
- if self.context.get("request") and hasattr(self.context["request"], "user"):
231
- validated_data["user_id"] = self.context["request"].user.id
232
- return super().create(validated_data)