diff --git a/Plataform_Web/documentos/__pycache__/admin.cpython-314.pyc b/Plataform_Web/documentos/__pycache__/admin.cpython-314.pyc index c50c4ac..9ca0ba2 100644 Binary files a/Plataform_Web/documentos/__pycache__/admin.cpython-314.pyc and b/Plataform_Web/documentos/__pycache__/admin.cpython-314.pyc differ diff --git a/Plataform_Web/documentos/__pycache__/models.cpython-314.pyc b/Plataform_Web/documentos/__pycache__/models.cpython-314.pyc index a7eff1d..b64606a 100644 Binary files a/Plataform_Web/documentos/__pycache__/models.cpython-314.pyc and b/Plataform_Web/documentos/__pycache__/models.cpython-314.pyc differ diff --git a/Plataform_Web/documentos/admin.py b/Plataform_Web/documentos/admin.py index 97dc990..d14f08f 100644 --- a/Plataform_Web/documentos/admin.py +++ b/Plataform_Web/documentos/admin.py @@ -1,13 +1,38 @@ from django.contrib import admin -from .models import Documento +from .models import Documento, Factura @admin.register(Documento) class DocumentoAdmin(admin.ModelAdmin): - list_display = ('titulo', 'categoria', 'tipo', 'temporada', 'subido_por', 'fecha_subida') - list_filter = ('temporada', 'categoria', 'tipo') # ¡Filtros laterales muy útiles! - search_fields = ('titulo', 'descripcion') + # Columnas principales + list_display = ('nombre', 'categoria', 'tipo', 'subido_por', 'fecha_subida') - # Esto hace que el campo "subido_por" se rellene solo con tu usuario al crear un doc + # Filtros por área técnica, tipo de documento y temporada del documento + list_filter = ('categoria', 'tipo', 'temporada') + + # Buscador de documentos por su nombre o descripción + search_fields = ('nombre', 'descripcion') + + # Para asignar a que temporada pertenece el documento + filter_horizontal = ('temporada',) + + # Automatización: para rellenar el creador del nuevo documento de manera automática + def save_model(self, request, obj, form, change): + if not obj.subido_por: + obj.subido_por = request.user + super().save_model(request, obj, form, change) + + +@admin.register(Factura) +class FacturaAdmin(admin.ModelAdmin): + # Herncia de Documento + list_display = ('nombre', 'empresa', 'importe', 'categoria', 'subido_por', 'fecha_subida') + + list_filter = ('categoria', 'temporada') + search_fields = ('nombre', 'empresa', 'descripcion') + + filter_horizontal = ('temporada',) + + # Mantenemos la misma automatización def save_model(self, request, obj, form, change): if not obj.subido_por: obj.subido_por = request.user diff --git a/Plataform_Web/documentos/migrations/0002_factura_alter_documento_options_and_more.py b/Plataform_Web/documentos/migrations/0002_factura_alter_documento_options_and_more.py new file mode 100644 index 0000000..d29ff00 --- /dev/null +++ b/Plataform_Web/documentos/migrations/0002_factura_alter_documento_options_and_more.py @@ -0,0 +1,66 @@ +# Generated by Django 6.0.2 on 2026-03-06 19:29 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('documentos', '0001_initial'), + ('temporadas', '0002_temporada_miembros'), + ] + + operations = [ + migrations.CreateModel( + name='Factura', + fields=[ + ('documento_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='documentos.documento')), + ('empresa', models.CharField(max_length=100, verbose_name='Nombre de la empresa')), + ('importe', models.DecimalField(decimal_places=2, max_digits=10, verbose_name='Importe (€)')), + ], + options={ + 'verbose_name': 'Factura', + 'verbose_name_plural': 'Facturas', + }, + bases=('documentos.documento',), + ), + migrations.AlterModelOptions( + name='documento', + options={'ordering': ['-fecha_subida'], 'verbose_name': 'Documento', 'verbose_name_plural': 'Documentos'}, + ), + migrations.RemoveField( + model_name='documento', + name='titulo', + ), + migrations.AddField( + model_name='documento', + name='nombre', + field=models.CharField(default='Documento antiguo', max_length=100, verbose_name='Nombre del documento'), + preserve_default=False, + ), + migrations.AlterField( + model_name='documento', + name='categoria', + field=models.CharField(choices=[('aerodinamica', 'Aerodinámica'), ('chasis', 'Chasis'), ('business', 'Business & Operations'), ('e_powertrain', 'E-Powertrain'), ('electronica', 'Electrónica'), ('sdf', 'SDF'), ('motor_transmision', 'Motor & Transmisión'), ('software', 'Software'), ('normativa', 'General / Normativa')], max_length=20), + ), + migrations.AlterField( + model_name='documento', + name='descripcion', + field=models.TextField(blank=True, null=True, verbose_name='Descripción del documento'), + ), + migrations.RemoveField( + model_name='documento', + name='temporada', + ), + migrations.AlterField( + model_name='documento', + name='tipo', + field=models.CharField(choices=[('fabricacion', 'Fabricación'), ('diseno', 'Diseño / CAD'), ('concepto', 'Concepto'), ('simulacion', 'Simulación'), ('dossier_patrocinado', 'Dossier Patrocinio'), ('informe', 'Informe'), ('tutorial', 'Tutorial'), ('otro', 'Otro')], default='informe', max_length=20), + ), + migrations.AddField( + model_name='documento', + name='temporada', + field=models.ManyToManyField(related_name='documentos_asociados', to='temporadas.temporada'), + ), + ] diff --git a/Plataform_Web/documentos/migrations/__pycache__/0002_factura_alter_documento_options_and_more.cpython-314.pyc b/Plataform_Web/documentos/migrations/__pycache__/0002_factura_alter_documento_options_and_more.cpython-314.pyc new file mode 100644 index 0000000..0cf2119 Binary files /dev/null and b/Plataform_Web/documentos/migrations/__pycache__/0002_factura_alter_documento_options_and_more.cpython-314.pyc differ diff --git a/Plataform_Web/documentos/models.py b/Plataform_Web/documentos/models.py index a4370f8..0d8c6c9 100644 --- a/Plataform_Web/documentos/models.py +++ b/Plataform_Web/documentos/models.py @@ -23,7 +23,7 @@ class Documento(models.Model): ('concepto', 'Concepto'), ('simulacion', 'Simulación'), ('dossier_patrocinado', 'Dossier Patrocinio'), - ('informe', 'Informe') + ('informe', 'Informe'), ('tutorial', 'Tutorial'), ('otro', 'Otro'), ) @@ -53,7 +53,7 @@ class Documento(models.Model): ordering = ['-fecha_subida'] def __str__(self): - return f"{self.nombre} ({self.temporada})" + return f"{self.nombre} ({self.get_categoria_display()})" def delete(self, *args, **kwargs): # Esto borra el archivo físico del disco duro cuando borras la entrada en la base de datos diff --git a/Plataform_Web/gestion/__pycache__/admin.cpython-314.pyc b/Plataform_Web/gestion/__pycache__/admin.cpython-314.pyc index fcd2106..2383af1 100644 Binary files a/Plataform_Web/gestion/__pycache__/admin.cpython-314.pyc and b/Plataform_Web/gestion/__pycache__/admin.cpython-314.pyc differ diff --git a/Plataform_Web/gestion/__pycache__/models.cpython-314.pyc b/Plataform_Web/gestion/__pycache__/models.cpython-314.pyc index 2aac323..171f35c 100644 Binary files a/Plataform_Web/gestion/__pycache__/models.cpython-314.pyc and b/Plataform_Web/gestion/__pycache__/models.cpython-314.pyc differ diff --git a/Plataform_Web/gestion/admin.py b/Plataform_Web/gestion/admin.py index daffb6a..0d47392 100644 --- a/Plataform_Web/gestion/admin.py +++ b/Plataform_Web/gestion/admin.py @@ -1,14 +1,46 @@ from django.contrib import admin -from .models import Factura, Patrocinador +from .models import Patrocinio, Pieza, Gasto, Ingreso -@admin.register(Factura) -class FacturaAdmin(admin.ModelAdmin): - list_display = ('nombre', 'empresa', 'categoria', 'temporada', 'subido_por') +# INLINES +class PiezaInline(admin.TabularInline): + model = Pieza + extra = 1 + +# PANEL PARA ADMINISTRACIÓN +@admin.register(Patrocinio) +class PatrocinioAdmin(admin.ModelAdmin): + list_display = ('empresa', 'estado', 'tipo_patrocinio', 'importe_economico', 'temporada', 'contacto_equipo') + + # Para editar el estado y pasar de En contacto a Aceptado o Denagado desde la lista, sin tener que hacerlo manual + list_editable = ('estado',) + + list_filter = ('estado', 'tipo_patrocinio', 'temporada') + search_fields = ('empresa', 'persona_contacto', 'email_contacto') + + # Metemos las piezas en el patrocinio, por si hiciera falta + inlines = [PiezaInline] + +@admin.register(Pieza) +class PiezaAdmin(admin.ModelAdmin): + list_display = ('nombre', 'cantidad', 'patrocinio') + search_fields = ('nombre', 'patrocinio__empresa') + +# CONTABILIDAD (Gastos e Ingresos) +@admin.register(Gasto) +class GastoAdmin(admin.ModelAdmin): + # Heredamos los campos de Contabilidad + list_display = ('concepto', 'importe', 'categoria', 'fecha', 'temporada') list_filter = ('categoria', 'temporada') - search_fields = ('nombre', 'empresa') + search_fields = ('concepto', 'observaciones') + + # Barra de navegación por fecha de gasto + date_hierarchy = 'fecha' -@admin.register(Patrocinador) -class PatrocinadorAdmin(admin.ModelAdmin): - list_display = ('empresa', 'tipo_empresa', 'tipo_patrocinio', 'estado', 'temporada') - list_filter = ('estado', 'tipo_empresa', 'tipo_patrocinio', 'temporada') - search_fields = ('empresa', 'email_contacto') \ No newline at end of file +@admin.register(Ingreso) +class IngresoAdmin(admin.ModelAdmin): + list_display = ('concepto', 'importe', 'categoria', 'fecha', 'temporada') + list_filter = ('categoria', 'temporada') + search_fields = ('concepto', 'observaciones') + + # Barra de navegación por fecha de ingreso + date_hierarchy = 'fecha' \ No newline at end of file diff --git a/Plataform_Web/gestion/migrations/0002_remove_patrocinador_contacto_equipo_and_more.py b/Plataform_Web/gestion/migrations/0002_remove_patrocinador_contacto_equipo_and_more.py new file mode 100644 index 0000000..84fb76c --- /dev/null +++ b/Plataform_Web/gestion/migrations/0002_remove_patrocinador_contacto_equipo_and_more.py @@ -0,0 +1,92 @@ +# Generated by Django 6.0.2 on 2026-03-06 19:29 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('gestion', '0001_initial'), + ('temporadas', '0002_temporada_miembros'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.RemoveField( + model_name='patrocinador', + name='contacto_equipo', + ), + migrations.RemoveField( + model_name='patrocinador', + name='temporada', + ), + migrations.CreateModel( + name='Gasto', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('concepto', models.CharField(max_length=150)), + ('importe', models.DecimalField(decimal_places=2, max_digits=10)), + ('fecha', models.DateField()), + ('observaciones', models.TextField(blank=True, null=True)), + ('categoria', models.CharField(choices=[('aerodinamica', 'Aerodinámica'), ('chasis', 'Chasis'), ('business', 'Business & Operations'), ('e_powertrain', 'E-Powertrain'), ('electronica', 'Electrónica'), ('sdf', 'SDF'), ('motor_transmision', 'Motor & Transmisión'), ('software', 'Software'), ('general', 'General')], max_length=30, verbose_name='Área del gasto')), + ('doc_justificativo', models.FileField(blank=True, null=True, upload_to='contabilidad/gastos/', verbose_name='Ticket o Factura (PDF/IMG)')), + ('temporada', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='%(class)s_registrados', to='temporadas.temporada')), + ], + options={ + 'verbose_name': 'Gasto', + 'verbose_name_plural': 'Gastos', + }, + ), + migrations.CreateModel( + name='Ingreso', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('concepto', models.CharField(max_length=150)), + ('importe', models.DecimalField(decimal_places=2, max_digits=10)), + ('fecha', models.DateField()), + ('observaciones', models.TextField(blank=True, null=True)), + ('categoria', models.CharField(choices=[('patrocinador', 'Patrocinador'), ('donación', 'Donación'), ('premio', 'Premio'), ('recaudación', 'Recaudación'), ('Cuotas', 'Cuotas'), ('Ventas', 'ventas')], max_length=30, verbose_name='Categoria del Ingreso')), + ('temporada', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='%(class)s_registrados', to='temporadas.temporada')), + ], + options={ + 'verbose_name': 'Ingreso', + 'verbose_name_plural': 'Ingresos', + }, + ), + migrations.CreateModel( + name='Patrocinio', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('empresa', models.CharField(max_length=100, verbose_name='Nombre de la Empresa')), + ('persona_contacto', models.CharField(blank=True, max_length=100, null=True, verbose_name='Persona de contacto')), + ('email_contacto', models.EmailField(max_length=254, verbose_name='Correo de contacto')), + ('tipo_patrocinio', models.CharField(choices=[('economico', 'Económico'), ('piezas/materiales', 'Piezas/Materiales'), ('mixto', 'Mixto (Dinero y Piezas)')], max_length=30)), + ('estado', models.CharField(choices=[('en_contacto', 'En contacto'), ('aceptado', 'Aceptado / Activo'), ('denegado', 'Denegado')], default='en_contacto', max_length=20)), + ('importe_economico', models.DecimalField(decimal_places=2, default=0.0, max_digits=10, verbose_name='Importe (€)')), + ('fecha_contacto', models.DateField(auto_now_add=True)), + ('contacto_equipo', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='patrocinios_gestionados', to=settings.AUTH_USER_MODEL, verbose_name='Persona al cargo del Patrocinio')), + ('temporada', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='patrocinios', to='temporadas.temporada', verbose_name='Temporada del patrocinio')), + ], + options={ + 'verbose_name': 'Patrocinio', + 'verbose_name_plural': 'Patrocinios', + }, + ), + migrations.CreateModel( + name='Pieza', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nombre', models.CharField(max_length=100, verbose_name='Nombre de la pieza/material')), + ('cantidad', models.PositiveIntegerField(default=1)), + ('patrocinio', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='piezas', to='gestion.patrocinio')), + ], + ), + migrations.DeleteModel( + name='Factura', + ), + migrations.DeleteModel( + name='Patrocinador', + ), + ] diff --git a/Plataform_Web/gestion/migrations/__pycache__/0002_remove_patrocinador_contacto_equipo_and_more.cpython-314.pyc b/Plataform_Web/gestion/migrations/__pycache__/0002_remove_patrocinador_contacto_equipo_and_more.cpython-314.pyc new file mode 100644 index 0000000..23ba326 Binary files /dev/null and b/Plataform_Web/gestion/migrations/__pycache__/0002_remove_patrocinador_contacto_equipo_and_more.cpython-314.pyc differ diff --git a/Plataform_Web/pruebas/__pycache__/admin.cpython-314.pyc b/Plataform_Web/pruebas/__pycache__/admin.cpython-314.pyc index fd6e07b..bfe8d02 100644 Binary files a/Plataform_Web/pruebas/__pycache__/admin.cpython-314.pyc and b/Plataform_Web/pruebas/__pycache__/admin.cpython-314.pyc differ diff --git a/Plataform_Web/pruebas/__pycache__/models.cpython-314.pyc b/Plataform_Web/pruebas/__pycache__/models.cpython-314.pyc index 7bf4367..5a56fd1 100644 Binary files a/Plataform_Web/pruebas/__pycache__/models.cpython-314.pyc and b/Plataform_Web/pruebas/__pycache__/models.cpython-314.pyc differ diff --git a/Plataform_Web/pruebas/admin.py b/Plataform_Web/pruebas/admin.py index b7de1ae..c2bb061 100644 --- a/Plataform_Web/pruebas/admin.py +++ b/Plataform_Web/pruebas/admin.py @@ -1,8 +1,50 @@ from django.contrib import admin -from .models import TestGeneral +from .models import Prueba, Telemetria, Variable -@admin.register(TestGeneral) -class TestGeneralAdmin(admin.ModelAdmin): - list_display = ('nombre', 'fecha_inicio', 'fecha_fin', 'categoria', 'temporada') +# INLINES +# Usamos inlines que nos sirve para cuando se este creando un registro de Telemetría, podremos añadir sus Variables en la misma pantalla sin tener que ir a otro menú +class VariableInline(admin.TabularInline): + model = Variable + extra = 1 + +class TelemetriaInline(admin.TabularInline): + model = Telemetria + extra = 0 + +# PANELES DE ADMINISTRACIÓN +@admin.register(Prueba) +class PruebaAdmin(admin.ModelAdmin): + list_display = ('nombre', 'categoria', 'fecha_inicio', 'temporada', 'realizado_por') + + # Filtros para encontrar los test dado una temporada y una área técnica list_filter = ('categoria', 'temporada') - search_fields = ('nombre', 'descripcion', 'resultados') \ No newline at end of file + + # Buscador de texto + search_fields = ('nombre', 'descripcion', 'resultados') + + # Una barra de navegación en la parte superior, para poder hacer clic en un año y en un mes y mostrar todos los datos de ese me + date_hierarchy = 'fecha_inicio' + + # Mostramos los archivos de telemetría directamente dentro del test + inlines = [TelemetriaInline] + + +@admin.register(Telemetria) +class TelemetriaAdmin(admin.ModelAdmin): + list_display = ('nombre', 'prueba', 'fecha_subida') + + # Filtra test de telemetría basandose en la temporada o área tecnica de su test correspondiente + list_filter = ('prueba__temporada', 'prueba__categoria') + + # Buscador del nombre de la telemetría o por el nombre de la prueba + search_fields = ('nombre', 'prueba__nombre') + + # Mostramos las variables de su telemetría + inlines = [VariableInline] + + +@admin.register(Variable) +class VariableAdmin(admin.ModelAdmin): + # Aunque se pueden crear desde el Inline, dejamos su tabla propia por si fuese necesario, por prevenir + list_display = ('nombre', 'unidad_medida', 'telemetria') + search_fields = ('nombre', 'telemetria__nombre') \ No newline at end of file diff --git a/Plataform_Web/pruebas/migrations/0002_prueba_telemetria_variable_delete_testgeneral.py b/Plataform_Web/pruebas/migrations/0002_prueba_telemetria_variable_delete_testgeneral.py new file mode 100644 index 0000000..8bc4e3b --- /dev/null +++ b/Plataform_Web/pruebas/migrations/0002_prueba_telemetria_variable_delete_testgeneral.py @@ -0,0 +1,67 @@ +# Generated by Django 6.0.2 on 2026-03-06 19:29 + +import django.db.models.deletion +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pruebas', '0001_initial'), + ('temporadas', '0002_temporada_miembros'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.CreateModel( + name='Prueba', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nombre', models.CharField(max_length=150, verbose_name='Nombre del Test')), + ('descripcion', models.TextField(verbose_name='Objetivo / Descripción de la prueba')), + ('fecha_inicio', models.DateField()), + ('fecha_fin', models.DateField()), + ('categoria', models.CharField(choices=[('aerodinamica', 'Aerodinámica'), ('chasis', 'Chasis'), ('epowertrain', 'E-Powertrain'), ('electronica', 'Electrónica'), ('sdf', 'SDF'), ('motor_transmision', 'Motor & Transmisión'), ('software', 'Software'), ('general', 'General')], default='general', max_length=30)), + ('resultados', models.TextField(blank=True, null=True, verbose_name='Conclusiones y Resultados')), + ('realizado_por', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='pruebas_realizadas', to=settings.AUTH_USER_MODEL, verbose_name='Realizado por')), + ('temporada', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pruebas', to='temporadas.temporada')), + ], + options={ + 'verbose_name': 'Prueba', + 'verbose_name_plural': 'Pruebas', + 'ordering': ['-fecha_inicio'], + }, + ), + migrations.CreateModel( + name='Telemetria', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nombre', models.CharField(max_length=100, verbose_name='Nombre del registro')), + ('archivo_csv', models.FileField(upload_to='telemetria/archivos_csv/', verbose_name='Archivo de Datos (CSV)')), + ('fecha_subida', models.DateTimeField(auto_now_add=True)), + ('prueba', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='archivos_telemetria', to='pruebas.prueba')), + ], + options={ + 'verbose_name': 'Registro de Telemetría', + 'verbose_name_plural': 'Registros de Telemetría', + }, + ), + migrations.CreateModel( + name='Variable', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('nombre', models.CharField(max_length=50, verbose_name='Nombre ')), + ('unidad_medida', models.CharField(blank=True, max_length=20, null=True, verbose_name='Unidad de medida')), + ('descripcion', models.TextField(blank=True, null=True)), + ('telemetria', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='variables', to='pruebas.telemetria')), + ], + options={ + 'verbose_name': 'Variable de Telemetría', + 'verbose_name_plural': 'Variables de Telemetría', + }, + ), + migrations.DeleteModel( + name='TestGeneral', + ), + ] diff --git a/Plataform_Web/pruebas/migrations/__pycache__/0002_prueba_telemetria_variable_delete_testgeneral.cpython-314.pyc b/Plataform_Web/pruebas/migrations/__pycache__/0002_prueba_telemetria_variable_delete_testgeneral.cpython-314.pyc new file mode 100644 index 0000000..91a8eb9 Binary files /dev/null and b/Plataform_Web/pruebas/migrations/__pycache__/0002_prueba_telemetria_variable_delete_testgeneral.cpython-314.pyc differ diff --git a/Plataform_Web/temporadas/__pycache__/admin.cpython-314.pyc b/Plataform_Web/temporadas/__pycache__/admin.cpython-314.pyc index c57527b..c681e16 100644 Binary files a/Plataform_Web/temporadas/__pycache__/admin.cpython-314.pyc and b/Plataform_Web/temporadas/__pycache__/admin.cpython-314.pyc differ diff --git a/Plataform_Web/temporadas/__pycache__/models.cpython-314.pyc b/Plataform_Web/temporadas/__pycache__/models.cpython-314.pyc index 3413456..d51e4dd 100644 Binary files a/Plataform_Web/temporadas/__pycache__/models.cpython-314.pyc and b/Plataform_Web/temporadas/__pycache__/models.cpython-314.pyc differ diff --git a/Plataform_Web/temporadas/admin.py b/Plataform_Web/temporadas/admin.py index 8345ef7..8420191 100644 --- a/Plataform_Web/temporadas/admin.py +++ b/Plataform_Web/temporadas/admin.py @@ -3,11 +3,17 @@ from .models import Temporada @admin.register(Temporada) class TemporadaAdmin(admin.ModelAdmin): - # Esto define qué columnas se ven en la lista + # Columnas principales. list_display = ('nombre', 'fecha_inicio', 'fecha_fin', 'presupuesto', 'actual') - # Esto añade un filtro a la derecha para ver rápido cuál es la actual + # Permite marcar o desmarcar el check de "actual" directamente desde la tabla, sin entrar al detalle + list_editable = ('actual',) + + # Filtro para filtrar por temporadas históricas o actual list_filter = ('actual',) - # Esto añade una barra de búsqueda por nombre - search_fields = ('nombre',) \ No newline at end of file + # Buscador de temporadas por nombre + search_fields = ('nombre',) + + # Filtro para ver los miembros de una temporada + filter_horizontal = ('miembros',) \ No newline at end of file diff --git a/Plataform_Web/temporadas/migrations/0002_temporada_miembros.py b/Plataform_Web/temporadas/migrations/0002_temporada_miembros.py new file mode 100644 index 0000000..b32fb3d --- /dev/null +++ b/Plataform_Web/temporadas/migrations/0002_temporada_miembros.py @@ -0,0 +1,20 @@ +# Generated by Django 6.0.2 on 2026-03-06 19:29 + +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('temporadas', '0001_initial'), + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ] + + operations = [ + migrations.AddField( + model_name='temporada', + name='miembros', + field=models.ManyToManyField(blank=True, related_name='temporadas_participadas', to=settings.AUTH_USER_MODEL, verbose_name='Miembros del equipo'), + ), + ] diff --git a/Plataform_Web/temporadas/migrations/__pycache__/0002_temporada_miembros.cpython-314.pyc b/Plataform_Web/temporadas/migrations/__pycache__/0002_temporada_miembros.cpython-314.pyc new file mode 100644 index 0000000..9c4ed0a Binary files /dev/null and b/Plataform_Web/temporadas/migrations/__pycache__/0002_temporada_miembros.cpython-314.pyc differ diff --git a/Plataform_Web/users/__pycache__/admin.cpython-314.pyc b/Plataform_Web/users/__pycache__/admin.cpython-314.pyc index de243a5..5f5d836 100644 Binary files a/Plataform_Web/users/__pycache__/admin.cpython-314.pyc and b/Plataform_Web/users/__pycache__/admin.cpython-314.pyc differ diff --git a/Plataform_Web/users/__pycache__/models.cpython-314.pyc b/Plataform_Web/users/__pycache__/models.cpython-314.pyc index 1835ea8..8a163f4 100644 Binary files a/Plataform_Web/users/__pycache__/models.cpython-314.pyc and b/Plataform_Web/users/__pycache__/models.cpython-314.pyc differ diff --git a/Plataform_Web/users/admin.py b/Plataform_Web/users/admin.py index b797f2c..81671c8 100644 --- a/Plataform_Web/users/admin.py +++ b/Plataform_Web/users/admin.py @@ -2,17 +2,26 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin from .models import CustomUser +@admin.register(CustomUser) class CustomUserAdmin(UserAdmin): - model = CustomUser + list_display = ('username', 'first_name', 'last_name', 'rol', 'especialidad', 'is_staff') - # Esto añade una sección nueva al editar un usuario existente + # Filtramos por rol y área técnica + list_filter = ('rol', 'especialidad', 'is_staff', 'is_active') + + # Buscador de usuarios + search_fields = ('username', 'first_name', 'last_name', 'email') + + # Para editar al usuario con los datos insertados fieldsets = UserAdmin.fieldsets + ( - ('Información del Equipo (TFG)', {'fields': ('rol', 'especialidad')}), + ('Información del Equipo Gades', { + 'fields': ('rol', 'especialidad'), + }), ) - # Esto permite añadir estos campos cuando creas un usuario nuevo desde el admin + # Para crear al usuario con los datos insertados add_fieldsets = UserAdmin.add_fieldsets + ( - ('Información del Equipo (TFG)', {'fields': ('rol', 'especialidad')}), - ) - -admin.site.register(CustomUser, CustomUserAdmin) \ No newline at end of file + ('Información del Equipo Gades', { + 'fields': ('rol', 'especialidad'), + }), + ) \ No newline at end of file diff --git a/Plataform_Web/users/migrations/0003_alter_customuser_especialidad_alter_customuser_rol.py b/Plataform_Web/users/migrations/0003_alter_customuser_especialidad_alter_customuser_rol.py new file mode 100644 index 0000000..68dc9a3 --- /dev/null +++ b/Plataform_Web/users/migrations/0003_alter_customuser_especialidad_alter_customuser_rol.py @@ -0,0 +1,23 @@ +# Generated by Django 6.0.2 on 2026-03-06 19:29 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('users', '0002_alter_customuser_especialidad_alter_customuser_rol'), + ] + + operations = [ + migrations.AlterField( + model_name='customuser', + name='especialidad', + field=models.CharField(blank=True, choices=[('aerodinamica', 'Aerodinámica'), ('chasis', 'Chasis'), ('business_operations', 'Business & Operations'), ('epowertrain', 'E-Powertrain'), ('electronica', 'Electrónica'), ('sdf', 'SDF'), ('motor_transmision', 'Motor & Transmisión'), ('software', 'Software')], max_length=30, null=True, verbose_name='Área Técnica'), + ), + migrations.AlterField( + model_name='customuser', + name='rol', + field=models.CharField(choices=[('directiva', 'Directiva'), ('jefe_area', 'Jefe de Área'), ('miembro', 'Miembro')], default='miembro', max_length=20, verbose_name='Rol en el equipo'), + ), + ] diff --git a/Plataform_Web/users/migrations/__pycache__/0003_alter_customuser_especialidad_alter_customuser_rol.cpython-314.pyc b/Plataform_Web/users/migrations/__pycache__/0003_alter_customuser_especialidad_alter_customuser_rol.cpython-314.pyc new file mode 100644 index 0000000..e521688 Binary files /dev/null and b/Plataform_Web/users/migrations/__pycache__/0003_alter_customuser_especialidad_alter_customuser_rol.cpython-314.pyc differ