diff --git a/becas_cozcyt/settings.py b/becas_cozcyt/settings.py index ce6d9a67e908bac9d905233320fffe98f7475f06..277b7433eb9f75862968d3b47bba3dbf938fe531 100644 --- a/becas_cozcyt/settings.py +++ b/becas_cozcyt/settings.py @@ -62,6 +62,12 @@ MIDDLEWARE = [ "django_htmx.middleware.HtmxMiddleware", ] +CACHES = { + 'default': { + 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', + } +} + ROOT_URLCONF = 'becas_cozcyt.urls' TEMPLATES = [ @@ -75,6 +81,7 @@ TEMPLATES = [ 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', + 'usuarios.context_processors.cache_version', ], }, }, diff --git a/solicitudes/viewsAdmin.py b/solicitudes/viewsAdmin.py index f77ce534d1fee6cac9c0b02a052a6fbe748093f5..b5df93ab5e64eeb007078329c7b0962f5c26501a 100644 --- a/solicitudes/viewsAdmin.py +++ b/solicitudes/viewsAdmin.py @@ -99,8 +99,7 @@ ESTADISTICAS_SOLICITUD_CHOICES = [ ] ESTADISTICAS_SOLICITUD_CHOICES_EXCLUDE_USER = [ - 'puntaje', - 'estado solicitud', + 'puntaje', ] TODOS_STR = 'Todas' @@ -121,7 +120,7 @@ MAPEO_SOLICITUDES_CHOICES_ADMIN = { MAPEO_SOLICITUDES_CHOICES_USER = { 'modalidad': 'modalidad__nombre', 'ciclo': 'ciclo__nombre', - #'estado solicitud': 'estado', + 'estado solicitud': 'estado', 'tipo': 'tipo', 'genero': 'solicitante__genero', 'instituciones': 'solicitante__carrera__institucion__nombre', diff --git a/testMigracion.py b/testMigracion.py new file mode 100644 index 0000000000000000000000000000000000000000..07f2ba9c227d35f1845c11b58603feac450a8426 --- /dev/null +++ b/testMigracion.py @@ -0,0 +1,12 @@ +import os +import django +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'becas_cozcyt.settings') +django.setup() +from django.contrib.contenttypes.models import ContentType +from usuarios.models import Solicitante, Usuario, SiteColor +from django.conf import settings +from django.contrib.auth.models import Permission, Group, User + + + +load_colors_from_css() \ No newline at end of file diff --git a/usuarios/admin.py b/usuarios/admin.py index e9c9f6b4b692539da8feda0308a5144ade8e2c3e..5c0d08f942caff1600dfc153177f5172b4713150 100644 --- a/usuarios/admin.py +++ b/usuarios/admin.py @@ -65,4 +65,6 @@ admin.site.register(Carrera) admin.site.register(Institucion) admin.site.register(Municipio) admin.site.register(Estado) +admin.site.register(SiteColor) +admin.site.register(CacheVersion) diff --git a/usuarios/context_processors.py b/usuarios/context_processors.py new file mode 100644 index 0000000000000000000000000000000000000000..6aadeeee59a537b0083c9118314540a70d1ebe76 --- /dev/null +++ b/usuarios/context_processors.py @@ -0,0 +1,5 @@ +from .models import CacheVersion + +def cache_version(request): + version = CacheVersion.get_object() + return {'cache_version': version.version if version else ''} \ No newline at end of file diff --git a/usuarios/forms.py b/usuarios/forms.py index 0f3fe38da749cc0b8509a67204074f4e5cd0b61a..72220b8a027befbb98d9102482768ec76efdcf80 100644 --- a/usuarios/forms.py +++ b/usuarios/forms.py @@ -340,4 +340,25 @@ class AgregarAdminForm(UserCreationForm): } password1 = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control form-control-lg my-3', 'placeholder': 'Contraseña'})) - password2 = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control form-control-lg my-3', 'placeholder': 'Confirme su contraseña'})) \ No newline at end of file + password2 = forms.CharField(widget=forms.PasswordInput(attrs={'class': 'form-control form-control-lg my-3', 'placeholder': 'Confirme su contraseña'})) + + +class SiteColorForm(forms.ModelForm): + class Meta: + model = SiteColor + fields = ['color'] + labels = { + 'color': 'Color', + } + widgets = { + #'nombre': forms.TextInput(attrs={'disabled': 'disabled'}), + 'color': forms.TextInput(attrs={'class': 'jscolor', 'data-jscolor': '{}', }), + } + + def clean_value(self): + value = self.cleaned_data.get('value') + if not SiteColor.is_valid_color(value): + raise forms.ValidationError("Formato de color invalido. Usa #000000, rgb(0,0,0) o rgba(0,0,0).") + return value + +SiteColorFormSet = modelformset_factory(SiteColor, form=SiteColorForm, extra=0, can_delete=False) \ No newline at end of file diff --git a/usuarios/migrations/0002_creacion_SiteColor.py b/usuarios/migrations/0002_creacion_SiteColor.py new file mode 100644 index 0000000000000000000000000000000000000000..5ad7046ebf21d9c7f9d1fe4ad841258fa11895ba --- /dev/null +++ b/usuarios/migrations/0002_creacion_SiteColor.py @@ -0,0 +1,21 @@ +# Generated by Django 4.1.13 on 2024-05-16 19:49 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('usuarios', '0001_initial'), + ] + + operations = [ + migrations.CreateModel( + name='SiteColor', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=50, unique=True)), + ('color', models.CharField(max_length=20)), + ], + ), + ] diff --git a/usuarios/migrations/0003_alter_sitecolor_options_alter_sitecolor_color.py b/usuarios/migrations/0003_alter_sitecolor_options_alter_sitecolor_color.py new file mode 100644 index 0000000000000000000000000000000000000000..e8f25792f8a24949393899f0ef986447ac620b24 --- /dev/null +++ b/usuarios/migrations/0003_alter_sitecolor_options_alter_sitecolor_color.py @@ -0,0 +1,22 @@ +# Generated by Django 4.1.13 on 2024-05-16 21:09 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('usuarios', '0002_creacion_SiteColor'), + ] + + operations = [ + migrations.AlterModelOptions( + name='sitecolor', + options={'ordering': ['id']}, + ), + migrations.AlterField( + model_name='sitecolor', + name='color', + field=models.CharField(max_length=30), + ), + ] diff --git a/usuarios/migrations/0004_crear_cache_version.py b/usuarios/migrations/0004_crear_cache_version.py new file mode 100644 index 0000000000000000000000000000000000000000..8246c49c6f7d123442843b6596c36832a877c3a1 --- /dev/null +++ b/usuarios/migrations/0004_crear_cache_version.py @@ -0,0 +1,23 @@ +# Generated by Django 4.1.13 on 2024-05-17 18:23 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('usuarios', '0003_alter_sitecolor_options_alter_sitecolor_color'), + ] + + operations = [ + migrations.CreateModel( + name='CacheVersion', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('version', models.PositiveIntegerField(default=0, verbose_name='Version')), + ], + options={ + 'abstract': False, + }, + ), + ] diff --git a/usuarios/migrations/0005_aztializar_siteColors.py b/usuarios/migrations/0005_aztializar_siteColors.py new file mode 100644 index 0000000000000000000000000000000000000000..1f0c1364cfa8e6670fb944a37b7303ed130b984b --- /dev/null +++ b/usuarios/migrations/0005_aztializar_siteColors.py @@ -0,0 +1,18 @@ +# Generated by Django 4.1.13 on 2024-05-17 19:04 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('usuarios', '0004_crear_cache_version'), + ] + + operations = [ + migrations.RenameField( + model_name='sitecolor', + old_name='name', + new_name='nombre', + ), + ] diff --git a/usuarios/models.py b/usuarios/models.py index a210971ac47c9c0c8c375cf1c6e7ee7719ab2900..4b702b2a17e773d84d1bbb01ccaa52e9f161fdb6 100644 --- a/usuarios/models.py +++ b/usuarios/models.py @@ -6,7 +6,8 @@ from django.core.validators import MinLengthValidator, MaxLengthValidator from django.core.exceptions import ValidationError from django.db.models import Q from django.core.validators import MaxValueValidator, MinValueValidator -from modalidades.models import Ciclo +from modalidades.models import Ciclo, SingletonModel +import re class Estado(models.Model): @@ -276,4 +277,36 @@ class PuntajeMunicipio(models.Model): puntos = models.IntegerField(default=0) def __str__(self): - return f"PuntajeMun de {self.municipio} - {self.puntos} puntos" \ No newline at end of file + return f"PuntajeMun de {self.municipio} - {self.puntos} puntos" + +class SiteColor(models.Model): + nombre = models.CharField(max_length=50, unique=True) + color = models.CharField(max_length=30) + + class Meta: + ordering = ['id'] + + def __str__(self): + return f"{self.nombre}: {self.color}" + + def save(self, *args, **kwargs): + if not self.is_valid_color(self.color): + raise ValueError("Invalid color format") + if self.pk is not None: + original = SiteColor.objects.get(pk=self.pk) + self.nombre = original.nombre + super().save(*args, **kwargs) + + @staticmethod + def is_valid_color(value): + hex_pattern = re.compile(r'^#(?:[0-9a-fA-F]{3}){1,2}$') + rgb_pattern = re.compile(r'^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$') + rgba_pattern = re.compile(r'^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(0|1|0?\.\d+)\)$') + return bool(hex_pattern.match(value) or rgb_pattern.match(value) or rgba_pattern.match(value)) + + +class CacheVersion(SingletonModel): + version = models.PositiveIntegerField(verbose_name="Version", default=0) + + def __str__(self): + return self.version \ No newline at end of file diff --git a/usuarios/templates/admin/configColores.html b/usuarios/templates/admin/configColores.html new file mode 100644 index 0000000000000000000000000000000000000000..d71f4166218ec4ee6710b6a34cd600e60931a76c --- /dev/null +++ b/usuarios/templates/admin/configColores.html @@ -0,0 +1,99 @@ +{% extends 'base.html' %} + +{% block titulo %} +Configuración colores +{% endblock titulo %} + +{% block body %} + {% include 'admin/config_nav.html' %} + + +
Configuración de color del sitio
+