Martín Miranda

Merge branch 'feature/#36_visibilizar_includes_y_filtros' into 'develop'

Feature/#36 visibilizar includes y filtros



See merge request !30
@@ -5,4 +5,6 @@ from .models import Edicto, Precio @@ -5,4 +5,6 @@ from .models import Edicto, Precio
5 # Register your models here. 5 # Register your models here.
6 6
7 admin.site.register(Precio) 7 admin.site.register(Precio)
  8 +
  9 +
8 admin.site.register(Edicto) 10 admin.site.register(Edicto)
1 -from rest_framework import viewsets, filters, mixins, status, serializers 1 +from rest_framework import viewsets, filters, mixins, status
2 from django_filters.rest_framework import DjangoFilterBackend 2 from django_filters.rest_framework import DjangoFilterBackend
3 from rest_framework.response import Response 3 from rest_framework.response import Response
4 from rest_framework.permissions import IsAuthenticated 4 from rest_framework.permissions import IsAuthenticated
@@ -7,9 +7,10 @@ from datetime import datetime @@ -7,9 +7,10 @@ from datetime import datetime
7 7
8 from .models import Edicto, Precio 8 from .models import Edicto, Precio
9 from .serializer import EdictoSerializer, PrecioSerializer 9 from .serializer import EdictoSerializer, PrecioSerializer
10 -from .filters import EdictoFilter 10 +from .filters import EdictoFilter, PrecioFilter
  11 +from .pagination import CustomPagination
  12 +from .permissions import IsAdminOrAuthorized
11 from .utils import contador 13 from .utils import contador
12 -# from .precio import contador  
13 14
14 15
15 class EdictoViewSet(mixins.CreateModelMixin, 16 class EdictoViewSet(mixins.CreateModelMixin,
@@ -24,13 +25,15 @@ class EdictoViewSet(mixins.CreateModelMixin, @@ -24,13 +25,15 @@ class EdictoViewSet(mixins.CreateModelMixin,
24 filter_backends = (DjangoFilterBackend, filters.OrderingFilter) 25 filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
25 filterset_class = EdictoFilter 26 filterset_class = EdictoFilter
26 queryset = Edicto.objects.all() 27 queryset = Edicto.objects.all()
27 - ordering_fields = ('usuario__usuario', 'estado', 'fecha_publicacion', 'id',)  
28 - ordering = 'id' 28 + ordering_fields = ('usuario',)
  29 + ordering = 'usuario'
  30 + pagination_class = CustomPagination
29 31
30 def perform_create(self, serializer): 32 def perform_create(self, serializer):
31 edicto = self.request.data.get('cuerpo_edicto') 33 edicto = self.request.data.get('cuerpo_edicto')
32 cantidad_palabras = contador(edicto) 34 cantidad_palabras = contador(edicto)
33 - serializer.save(cantidad_palabras=cantidad_palabras, usuario=self.request.user) 35 + usuario = self.request.user
  36 + serializer.save(cantidad_palabras=cantidad_palabras, usuario=usuario)
34 37
35 @action(detail=True, methods=['put', 'patch']) 38 @action(detail=True, methods=['put', 'patch'])
36 def custom_update(self, request): 39 def custom_update(self, request):
@@ -45,26 +48,12 @@ class EdictoViewSet(mixins.CreateModelMixin, @@ -45,26 +48,12 @@ class EdictoViewSet(mixins.CreateModelMixin,
45 return Response(serializer.data, status=status.HTTP_200_OK) 48 return Response(serializer.data, status=status.HTTP_200_OK)
46 49
47 50
48 -class PrecioViewSet(mixins.CreateModelMixin,  
49 - mixins.RetrieveModelMixin,  
50 - mixins.ListModelMixin,  
51 - viewsets.GenericViewSet):  
52 -  
53 - queryset = Precio.objects.all().order_by('id') 51 +class PrecioViewSet(viewsets.ReadOnlyModelViewSet):
54 serializer_class = PrecioSerializer 52 serializer_class = PrecioSerializer
55 - permission_classes = [IsAuthenticated, ]  
56 -  
57 - def create(self, request, *args, **kwargs):  
58 - user = request.user  
59 -  
60 - if not user.is_staff:  
61 - raise serializers.ValidationError("El usuario no es parte del personal designado.")  
62 -  
63 - return super().create(request, *args, **kwargs)  
64 -  
65 - def retrieve(self, request, *args, **kwargs):  
66 - instance = self.get_object()  
67 - serializer = self.get_serializer(instance)  
68 - data = serializer.data  
69 - data['id'] = instance.id  
70 - return Response(data) 53 + permission_classes = [IsAuthenticated, IsAdminOrAuthorized]
  54 + filter_backends = (DjangoFilterBackend, filters.OrderingFilter)
  55 + filterset_class = PrecioFilter
  56 + ordering_fields = ('usuario', )
  57 + ordering = 'usuario'
  58 + queryset = Precio.objects.all()
  59 + pagination_class = CustomPagination
1 from django_filters import rest_framework as filters 1 from django_filters import rest_framework as filters
2 2
3 -from edicto.models import Edicto 3 +from edicto.models import Edicto, Precio
4 4
5 5
6 class EdictoFilter(filters.FilterSet): 6 class EdictoFilter(filters.FilterSet):
  7 + fecha_creacion__gte = filters.DateFilter(field_name="fecha_creacion", lookup_expr='gte', label='Desde')
  8 + fecha_creacion__lte = filters.DateFilter(field_name="fecha_creacion", lookup_expr='lte', label='Hasta')
  9 +
7 class Meta: 10 class Meta:
8 model = Edicto 11 model = Edicto
9 - fields = ('usuario', 'estado', 'fecha_publicacion', 'id',) 12 + fields = {'usuario': ['exact'],
  13 + 'estado': ['exact'],
  14 + 'id': ['exact'],
  15 + }
  16 +
  17 +
  18 +class PrecioFilter(filters.FilterSet):
  19 + class Meta:
  20 + model = Precio
  21 + fields = {
  22 + 'usuario': ['exact'],
  23 + 'precio': ['exact'],
  24 + 'vigencia_desde': ['exact'],
  25 + 'vigencia_hasta': ['exact'],
  26 + 'moneda': ['exact'],
  27 + }
10 28
11 29
12 30
  1 +from rest_framework.pagination import PageNumberPagination
  2 +
  3 +
  4 +class CustomPagination(PageNumberPagination):
  5 + page_size = 2
  6 + page_size_query_param = 'page_size'
  7 + max_page_size = 1000
  1 +from rest_framework import permissions
  2 +
  3 +
  4 +class IsAdminOrAuthorized(permissions.BasePermission):
  5 + def has_permission(self, request, view):
  6 + return request.user.is_staff or request.user.is_authenticated or request.user.is_authorized
1 from rest_framework import serializers 1 from rest_framework import serializers
2 2
  3 +
3 from .constants import EXTENSIONES_VALIDAS 4 from .constants import EXTENSIONES_VALIDAS
4 5
5 -from .models import Edicto, Precio, ComprobantePago  
6 -from usuario.serializers import UsuarioSerializer 6 +from .models import Edicto, Precio
  7 +from usuario.serializers import UsuarioListaSerializer
7 8
8 9
9 class EdictoSerializer(serializers.ModelSerializer): 10 class EdictoSerializer(serializers.ModelSerializer):
  11 + included_serializers = {
  12 + 'usuario': UsuarioListaSerializer,
  13 + }
10 14
11 class Meta: 15 class Meta:
12 model = Edicto 16 model = Edicto
@@ -21,11 +25,8 @@ class EdictoSerializer(serializers.ModelSerializer): @@ -21,11 +25,8 @@ class EdictoSerializer(serializers.ModelSerializer):
21 'fecha_creacion', 25 'fecha_creacion',
22 'observaciones', 26 'observaciones',
23 'fecha_publicacion', 27 'fecha_publicacion',
24 - )  
25 28
26 - included_serializers = {  
27 - 'usuario': 'username.serializers.UsuarioListaSerializer',  
28 - } 29 + )
29 30
30 read_only_fields = ('usuario', 'fecha_publicacion', 'cantidad_palabras', 'fecha_creacion') 31 read_only_fields = ('usuario', 'fecha_publicacion', 'cantidad_palabras', 'fecha_creacion')
31 32
@@ -45,7 +46,6 @@ class EdictoSerializer(serializers.ModelSerializer): @@ -45,7 +46,6 @@ class EdictoSerializer(serializers.ModelSerializer):
45 46
46 47
47 class PrecioSerializer(serializers.ModelSerializer): 48 class PrecioSerializer(serializers.ModelSerializer):
48 - usuario = UsuarioSerializer()  
49 49
50 class Meta: 50 class Meta:
51 model = Precio 51 model = Precio
@@ -57,12 +57,6 @@ class PrecioSerializer(serializers.ModelSerializer): @@ -57,12 +57,6 @@ class PrecioSerializer(serializers.ModelSerializer):
57 'vigencia_hasta', 57 'vigencia_hasta',
58 ) 58 )
59 59
60 - def validate(self, data):  
61 - request = self.context.get('request')  
62 - user = request.user if request else None  
63 - if not user or user.is_anonymous:  
64 - raise serializers.ValidationError("El usuario debe estar autenticado.")  
65 - if not user.is_staff:  
66 - raise serializers.ValidationError("El usuario no es parte del personal designado.")  
67 -  
68 - return data 60 + included_serializers = {
  61 + 'usuario': UsuarioListaSerializer
  62 + }
@@ -3,8 +3,7 @@ import re @@ -3,8 +3,7 @@ import re
3 3
4 def contador(edicto): 4 def contador(edicto):
5 expresiones = re.findall(r'\(\.\.\.', edicto) 5 expresiones = re.findall(r'\(\.\.\.', edicto)
6 - texto = edicto.split()  
7 - cantidad_palabras = len(texto)  
8 - cantidad_expresiones = len(expresiones)  
9 - total_edicto = cantidad_palabras + cantidad_expresiones  
10 - return total_edicto 6 + edicto_sin_guiones = re.sub(r'(?<!\w)-|-(?!\w)', ' ', edicto)
  7 + palabras = re.split(r'\s+', edicto_sin_guiones)
  8 + total_palabras = len(palabras) + len(expresiones)
  9 + return total_palabras
@@ -48,6 +48,7 @@ DJANGO_APPS = ( @@ -48,6 +48,7 @@ DJANGO_APPS = (
48 48
49 THIRD_PARTY_APPS = ( 49 THIRD_PARTY_APPS = (
50 'rest_framework', 50 'rest_framework',
  51 + 'rest_framework_json_api',
51 'django_filters', 52 'django_filters',
52 'corsheaders', 53 'corsheaders',
53 'oauth2_provider', 54 'oauth2_provider',
@@ -157,9 +158,24 @@ REST_FRAMEWORK = { @@ -157,9 +158,24 @@ REST_FRAMEWORK = {
157 'rest_framework.authentication.BasicAuthentication', 158 'rest_framework.authentication.BasicAuthentication',
158 'rest_framework.authentication.SessionAuthentication', 159 'rest_framework.authentication.SessionAuthentication',
159 ), 160 ),
160 - 'DEFAULT_RENDERER_CLASSES': ('rest_framework_json_api.renderers.JSONRenderer',), 161 + 'DEFAULT_RENDERER_CLASSES': (
  162 + 'rest_framework_json_api.renderers.JSONRenderer',
  163 + 'rest_framework_json_api.renderers.BrowsableAPIRenderer'
  164 + ),
161 'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata', 165 'DEFAULT_METADATA_CLASS': 'rest_framework_json_api.metadata.JSONAPIMetadata',
162 - 'NON_FIELD_ERRORS_KEY': 'error_messages' 166 + 'DEFAULT_FILTER_BACKENDS': (
  167 + 'rest_framework_json_api.filters.QueryParameterValidationFilter',
  168 + 'rest_framework_json_api.filters.OrderingFilter',
  169 + 'rest_framework_json_api.django_filters.DjangoFilterBackend',
  170 + 'rest_framework.filters.SearchFilter',
  171 + ),
  172 + 'SEARCH_PARAM': 'filter[search]',
  173 + 'TEST_REQUEST_RENDERER_CLASSES': (
  174 + 'rest_framework_json_api.renderers.JSONRenderer',
  175 + ),
  176 + 'TEST_REQUEST_DEFAULT_FORMAT': 'vnd.api+json',
  177 +
  178 +
163 } 179 }
164 180
165 ACTIVAR_HERRAMIENTAS_DEBUGGING = env.bool('ACTIVAR_HERRAMIENTAS_DEBUGGING', default=True) 181 ACTIVAR_HERRAMIENTAS_DEBUGGING = env.bool('ACTIVAR_HERRAMIENTAS_DEBUGGING', default=True)