mirror of
https://github.com/adrigongv23/G26---Telemetry-Software.git
synced 2026-08-25 11:33:17 +02:00
Admins.py configurados correctamente dados los cambios realizado en la base de datos
This commit is contained in:
parent
99426f7335
commit
e64a08326c
26 changed files with 416 additions and 34 deletions
Binary file not shown.
Binary file not shown.
|
|
@ -1,13 +1,38 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from .models import Documento
|
from .models import Documento, Factura
|
||||||
|
|
||||||
@admin.register(Documento)
|
@admin.register(Documento)
|
||||||
class DocumentoAdmin(admin.ModelAdmin):
|
class DocumentoAdmin(admin.ModelAdmin):
|
||||||
list_display = ('titulo', 'categoria', 'tipo', 'temporada', 'subido_por', 'fecha_subida')
|
# Columnas principales
|
||||||
list_filter = ('temporada', 'categoria', 'tipo') # ¡Filtros laterales muy útiles!
|
list_display = ('nombre', 'categoria', 'tipo', 'subido_por', 'fecha_subida')
|
||||||
search_fields = ('titulo', 'descripcion')
|
|
||||||
|
|
||||||
# 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):
|
def save_model(self, request, obj, form, change):
|
||||||
if not obj.subido_por:
|
if not obj.subido_por:
|
||||||
obj.subido_por = request.user
|
obj.subido_por = request.user
|
||||||
|
|
|
||||||
|
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
|
|
@ -23,7 +23,7 @@ class Documento(models.Model):
|
||||||
('concepto', 'Concepto'),
|
('concepto', 'Concepto'),
|
||||||
('simulacion', 'Simulación'),
|
('simulacion', 'Simulación'),
|
||||||
('dossier_patrocinado', 'Dossier Patrocinio'),
|
('dossier_patrocinado', 'Dossier Patrocinio'),
|
||||||
('informe', 'Informe')
|
('informe', 'Informe'),
|
||||||
('tutorial', 'Tutorial'),
|
('tutorial', 'Tutorial'),
|
||||||
('otro', 'Otro'),
|
('otro', 'Otro'),
|
||||||
)
|
)
|
||||||
|
|
@ -53,7 +53,7 @@ class Documento(models.Model):
|
||||||
ordering = ['-fecha_subida']
|
ordering = ['-fecha_subida']
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.nombre} ({self.temporada})"
|
return f"{self.nombre} ({self.get_categoria_display()})"
|
||||||
|
|
||||||
def delete(self, *args, **kwargs):
|
def delete(self, *args, **kwargs):
|
||||||
# Esto borra el archivo físico del disco duro cuando borras la entrada en la base de datos
|
# Esto borra el archivo físico del disco duro cuando borras la entrada en la base de datos
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,14 +1,46 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from .models import Factura, Patrocinador
|
from .models import Patrocinio, Pieza, Gasto, Ingreso
|
||||||
|
|
||||||
@admin.register(Factura)
|
# INLINES
|
||||||
class FacturaAdmin(admin.ModelAdmin):
|
class PiezaInline(admin.TabularInline):
|
||||||
list_display = ('nombre', 'empresa', 'categoria', 'temporada', 'subido_por')
|
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')
|
list_filter = ('categoria', 'temporada')
|
||||||
search_fields = ('nombre', 'empresa')
|
search_fields = ('concepto', 'observaciones')
|
||||||
|
|
||||||
@admin.register(Patrocinador)
|
# Barra de navegación por fecha de gasto
|
||||||
class PatrocinadorAdmin(admin.ModelAdmin):
|
date_hierarchy = 'fecha'
|
||||||
list_display = ('empresa', 'tipo_empresa', 'tipo_patrocinio', 'estado', 'temporada')
|
|
||||||
list_filter = ('estado', 'tipo_empresa', 'tipo_patrocinio', 'temporada')
|
@admin.register(Ingreso)
|
||||||
search_fields = ('empresa', 'email_contacto')
|
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'
|
||||||
|
|
@ -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',
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,8 +1,50 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from .models import TestGeneral
|
from .models import Prueba, Telemetria, Variable
|
||||||
|
|
||||||
@admin.register(TestGeneral)
|
# INLINES
|
||||||
class TestGeneralAdmin(admin.ModelAdmin):
|
# 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ú
|
||||||
list_display = ('nombre', 'fecha_inicio', 'fecha_fin', 'categoria', 'temporada')
|
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')
|
list_filter = ('categoria', 'temporada')
|
||||||
|
|
||||||
|
# Buscador de texto
|
||||||
search_fields = ('nombre', 'descripcion', 'resultados')
|
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')
|
||||||
|
|
@ -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',
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -3,11 +3,17 @@ from .models import Temporada
|
||||||
|
|
||||||
@admin.register(Temporada)
|
@admin.register(Temporada)
|
||||||
class TemporadaAdmin(admin.ModelAdmin):
|
class TemporadaAdmin(admin.ModelAdmin):
|
||||||
# Esto define qué columnas se ven en la lista
|
# Columnas principales.
|
||||||
list_display = ('nombre', 'fecha_inicio', 'fecha_fin', 'presupuesto', 'actual')
|
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',)
|
list_filter = ('actual',)
|
||||||
|
|
||||||
# Esto añade una barra de búsqueda por nombre
|
# Buscador de temporadas por nombre
|
||||||
search_fields = ('nombre',)
|
search_fields = ('nombre',)
|
||||||
|
|
||||||
|
# Filtro para ver los miembros de una temporada
|
||||||
|
filter_horizontal = ('miembros',)
|
||||||
|
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -2,17 +2,26 @@ from django.contrib import admin
|
||||||
from django.contrib.auth.admin import UserAdmin
|
from django.contrib.auth.admin import UserAdmin
|
||||||
from .models import CustomUser
|
from .models import CustomUser
|
||||||
|
|
||||||
|
@admin.register(CustomUser)
|
||||||
class CustomUserAdmin(UserAdmin):
|
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 + (
|
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 + (
|
add_fieldsets = UserAdmin.add_fieldsets + (
|
||||||
('Información del Equipo (TFG)', {'fields': ('rol', 'especialidad')}),
|
('Información del Equipo Gades', {
|
||||||
|
'fields': ('rol', 'especialidad'),
|
||||||
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
admin.site.register(CustomUser, CustomUserAdmin)
|
|
||||||
|
|
@ -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'),
|
||||||
|
),
|
||||||
|
]
|
||||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue