Enzo Yair

feature/organismo parte 1

@@ -24,7 +24,7 @@ logs @@ -24,7 +24,7 @@ logs
24 # Installer logs 24 # Installer logs
25 pip-log.txt 25 pip-log.txt
26 26
27 -# Unit test / coverage reports 27 +# Unit tests / coverage reports
28 .coverage 28 .coverage
29 .tox 29 .tox
30 nosetests.xml 30 nosetests.xml
@@ -28,7 +28,7 @@ def create_user(username, first_name='Admin', last_name='Root', email=None): @@ -28,7 +28,7 @@ def create_user(username, first_name='Admin', last_name='Root', email=None):
28 28
29 @pytest.fixture 29 @pytest.fixture
30 def get_default_test_user(): 30 def get_default_test_user():
31 - test_user = create_user(username='test_user', first_name='Test', last_name='User', email='test@user') 31 + test_user = create_user(username='test_user', first_name='Test', last_name='User', email='tests@user')
32 return test_user 32 return test_user
33 33
34 34
  1 +from django.contrib import admin
  2 +
  3 +from .models import Organismo, Dependencia
  4 +
  5 +# Register your models here.
  6 +
  7 +
  8 +@admin.register(Organismo)
  9 +class OrganismoAdmin(admin.ModelAdmin):
  10 + model = Organismo
  11 + list_display = ('id', 'short_name')
  12 + list_filter = ('short_name',)
  13 + search_fields = ('short_name', )
  14 +
  15 + def has_view_permission(self, request, obj=None):
  16 + if obj is not None:
  17 + return request.user.has_perm(f'organismo.view_{obj.short_name.lower().replace(" ", "_")}')
  18 + return request.user.has_perm('organismo.view_organismo')
  19 +
  20 + def has_add_permission(self, request):
  21 + return request.user.has_perm('organismo.create_organismo')
  22 +
  23 + def has_change_permission(self, request, obj=None):
  24 + if obj is not None:
  25 + return request.user.has_perm(f'organismo.edit_{obj.short_name.lower().replace(" ", "_")}')
  26 + return request.user.has_perm('organismo.edit_organismo')
  27 +
  28 + def has_delete_permission(self, request, obj=None):
  29 + if obj is not None:
  30 + return request.user.has_perm(f'organismo.delete_{obj.short_name.lower().replace(" ", "_")}')
  31 + return request.user.has_perm('organismo.delete_organismo')
  32 +
  33 +
  34 +@admin.register(Dependencia)
  35 +class DependenciaAdmin(admin.ModelAdmin):
  36 + model = Dependencia
  37 + list_display = ('id', 'organismo', 'short_name',)
  38 + list_filter = ('organismo', 'short_name',)
  39 + search_fields = ('short_name',)
  40 +
  41 + def get_queryset(self, request):
  42 + queryset = super().get_queryset(request)
  43 +
  44 + if not request.user.is_superuser:
  45 + user_groups = request.user.groups.all()
  46 +
  47 + return queryset
  1 +from rest_framework import viewsets
  2 +from rest_framework.permissions import IsAuthenticated
  3 +
  4 +from .models import Organismo, Dependencia
  5 +from .serializers import OrganismoSerializer, DependenciaSerializer
  6 +
  7 +
  8 +class OrganismoViewSets(viewsets.ReadOnlyModelViewSet):
  9 + queryset = Organismo.objects.all()
  10 + serializer_class = OrganismoSerializer
  11 + permission_classes = [IsAuthenticated, ]
  12 + lookup_field = 'id'
  13 +
  14 +
  15 +class DependenciaViewSets(viewsets.ReadOnlyModelViewSet):
  16 + queryset = Dependencia.objects.all()
  17 + serializer_class = DependenciaSerializer
  18 + permission_classes = [IsAuthenticated, ]
  19 + lookup_field = 'id'
  20 +
  1 +from django.apps import AppConfig
  2 +
  3 +
  4 +class OrganismoConfig(AppConfig):
  5 + default_auto_field = 'django.db.models.BigAutoField'
  6 + name = 'organismo'
  1 +# Generated by Django 4.2.9 on 2024-09-30 15:44
  2 +
  3 +from django.db import migrations, models
  4 +import django.db.models.deletion
  5 +
  6 +
  7 +class Migration(migrations.Migration):
  8 +
  9 + initial = True
  10 +
  11 + dependencies = [
  12 + ]
  13 +
  14 + operations = [
  15 + migrations.CreateModel(
  16 + name='Organismo',
  17 + fields=[
  18 + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  19 + ('short_name', models.CharField(max_length=350, verbose_name='Nombre del organismo')),
  20 + ],
  21 + options={
  22 + 'verbose_name': 'Organismo',
  23 + 'verbose_name_plural': 'Organismos',
  24 + },
  25 + ),
  26 + migrations.CreateModel(
  27 + name='Dependencia',
  28 + fields=[
  29 + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
  30 + ('short_name', models.CharField(max_length=350, verbose_name='Nombre de la dependencia')),
  31 + ('organismo', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organismo.organismo')),
  32 + ],
  33 + options={
  34 + 'verbose_name': 'Dependencia',
  35 + 'verbose_name_plural': 'Dependencias',
  36 + },
  37 + ),
  38 + ]
  1 +from django.db import models
  2 +
  3 +from django.db.models.signals import post_save
  4 +from django.contrib.auth.models import Permission
  5 +from django.contrib.contenttypes.models import ContentType
  6 +from django.dispatch import receiver
  7 +
  8 +# Create your models here.
  9 +
  10 +
  11 +class Organismo(models.Model):
  12 + class Meta:
  13 + verbose_name = 'Organismo'
  14 + verbose_name_plural = 'Organismos'
  15 +
  16 + short_name = models.CharField(max_length=350, blank=False, verbose_name='Nombre del organismo')
  17 +
  18 + def __str__(self):
  19 + return f'{self.short_name}'
  20 +
  21 +
  22 +def custom_permission_organismo_create(organismo):
  23 + content_type = ContentType.objects.get_for_model(Organismo)
  24 +
  25 + action = 'view'
  26 + codename = f'{action}_{organismo.short_name.lower().replace(" ", "_")}'
  27 + if not Permission.objects.filter(codename=codename, content_type=content_type).exists():
  28 + Permission.objects.create(
  29 + codename=codename,
  30 + name=f'Can {action} {organismo.short_name}',
  31 + content_type=content_type,
  32 + )
  33 +
  34 +
  35 +def custom_permission_organismo_delete(organismo):
  36 + content_type = ContentType.objects.get_for_model(Organismo)
  37 +
  38 + action = 'view'
  39 + codename = f'{action}_{organismo.short_name.lower().replace(" ", "_")}'
  40 + Permission.objects.filter(codename=codename, content_type=content_type).delete()
  41 +
  42 +
  43 +@receiver(post_save, sender=Organismo)
  44 +def manage_organismo_permissions(sender, instance, created, **kwargs):
  45 + if created:
  46 + custom_permission_organismo_create(instance)
  47 + else:
  48 + old_instance = Organismo.objects.get(pk=instance.pk)
  49 + if old_instance.short_name != instance.short_name:
  50 + custom_permission_organismo_create(old_instance)
  51 + custom_permission_organismo_delete(instance)
  52 +
  53 +
  54 +class Dependencia(models.Model):
  55 + objects = None
  56 +
  57 + class Meta:
  58 + verbose_name = 'Dependencia'
  59 + verbose_name_plural = 'Dependencias'
  60 +
  61 + organismo = models.ForeignKey('Organismo', on_delete=models.CASCADE)
  62 + short_name = models.CharField(max_length=350, blank=False, verbose_name='Nombre de la dependencia')
  63 +
  64 + def __str__(self):
  65 + return f'{self.organismo} - {self.short_name}'
  66 +
  67 +
  68 +def custom_permission_dependencia_create(dependencia):
  69 + content_type = ContentType.objects.get_for_model(dependencia)
  70 +
  71 + action = 'view'
  72 + codename = f'{action}_{dependencia.short_name.lower().replace(" ", "_")}'
  73 + if not Permission.objects.filter(codename=codename, content_type=content_type).exists():
  74 + Permission.objects.create(
  75 + codename=codename,
  76 + name=f'Can {action} {dependencia.short_name}',
  77 + content_type=content_type,
  78 + )
  79 +
  80 +
  81 +def custom_permissions_dependencia_delete(dependencia):
  82 + content_type = ContentType.objects.get_for_model(dependencia)
  83 +
  84 + action = 'view'
  85 + codename = f'{action}_{dependencia.short_name.lower().replace(" ", "_")}'
  86 + Permission.objects.filter(codename=codename, content_type=content_type).delete()
  87 +
  88 +
  89 +@receiver(post_save, sender=Dependencia)
  90 +def manage_dependencia_permissions(sender, instance, created, **kwargs):
  91 + if created:
  92 + custom_permission_dependencia_create(instance)
  93 + else:
  94 + old_instance = Organismo.objects.get(pk=instance.pk)
  95 + if old_instance.short_name != instance.short_name:
  96 + custom_permissions_dependencia_delete(old_instance)
  97 + custom_permission_dependencia_create(instance)
  1 +from rest_framework_json_api import serializers
  2 +
  3 +from .models import Dependencia, Organismo
  4 +
  5 +
  6 +class OrganismoSerializer(serializers.ModelSerializer):
  7 + class Meta:
  8 + model = Organismo
  9 + fields = serializers.ALL_FIELDS
  10 +
  11 +
  12 +class DependenciaSerializer(serializers.ModelSerializer):
  13 + class Meta:
  14 + model = Dependencia
  15 + fields = serializers.ALL_FIELDS
  1 +from django.test import TestCase
  2 +
  3 +# Create your tests here.
  1 +import factory
  2 +
  3 +from factory import SubFactory, faker, django
  4 +
  1 +from django.shortcuts import render
  2 +
  3 +# Create your views here.
1 from rest_framework import routers 1 from rest_framework import routers
2 2
  3 +from organismo import api as organismo_api
  4 +
3 # Define routes 5 # Define routes
4 router = routers.DefaultRouter() 6 router = routers.DefaultRouter()
  7 +
  8 +router.register(prefix='organismo', viewset=organismo_api.OrganismoViewSets)
  9 +router.register(prefix='dependencia', viewset=organismo_api.OrganismoViewSets)
@@ -59,6 +59,7 @@ THIRD_PARTY_APPS = ( @@ -59,6 +59,7 @@ THIRD_PARTY_APPS = (
59 59
60 PROJECT_APPS = ( 60 PROJECT_APPS = (
61 'core', 61 'core',
  62 + 'organismo',
62 ) 63 )
63 64
64 INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + PROJECT_APPS 65 INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + PROJECT_APPS
@@ -14,8 +14,9 @@ Including another URLconf @@ -14,8 +14,9 @@ Including another URLconf
14 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) 14 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15 """ 15 """
16 from django.contrib import admin 16 from django.contrib import admin
17 -from django.urls import path, include 17 +from django.urls import path, include, reverse_lazy
18 from django.conf import settings 18 from django.conf import settings
  19 +from django.views.generic.base import RedirectView
19 20
20 from .router import router 21 from .router import router
21 22
@@ -24,6 +25,7 @@ admin.site.site_header = getattr(settings, 'PROJECT_NAME_HEADER') @@ -24,6 +25,7 @@ admin.site.site_header = getattr(settings, 'PROJECT_NAME_HEADER')
24 admin.site.site_title = getattr(settings, 'PROJECT_NAME_TITLE') 25 admin.site.site_title = getattr(settings, 'PROJECT_NAME_TITLE')
25 26
26 urlpatterns = [ 27 urlpatterns = [
  28 + path('', RedirectView.as_view(url=reverse_lazy('admin:index'))),
27 path('admin/', admin.site.urls), 29 path('admin/', admin.site.urls),
28 path('api/v1/', include(router.urls)), 30 path('api/v1/', include(router.urls)),
29 ] 31 ]