Browse Source

Voy completando lyrics

politica
Celestino Rey 1 year ago
parent
commit
f185fab4db
19 changed files with 778 additions and 4 deletions
  1. BIN
      ReyMotaAppsDj/reymota/db.sqlite3
  2. +45
    -0
      ReyMotaAppsDj/reymota/lyrics/forms.py
  3. +52
    -0
      ReyMotaAppsDj/reymota/lyrics/migrations/0001_initial.py
  4. +42
    -1
      ReyMotaAppsDj/reymota/lyrics/models.py
  5. +27
    -0
      ReyMotaAppsDj/reymota/lyrics/urls.py
  6. +195
    -2
      ReyMotaAppsDj/reymota/lyrics/views.py
  7. +1
    -0
      ReyMotaAppsDj/reymota/reymota/settings.py
  8. +2
    -0
      ReyMotaAppsDj/reymota/reymota/urls.py
  9. +2
    -1
      ReyMotaAppsDj/reymota/templates/_cabecera.html
  10. +24
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/detalle_album.html
  11. +62
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/detalle_artista.html
  12. +32
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/detalle_song.html
  13. +17
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/form_album.html
  14. +17
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/form_artista.html
  15. +17
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/form_song.html
  16. +64
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/index.html
  17. +57
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/lista_albumes.html
  18. +65
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/lista_artistas.html
  19. +57
    -0
      ReyMotaAppsDj/reymota/templates/lyrics/lista_songs.html

BIN
ReyMotaAppsDj/reymota/db.sqlite3 View File


+ 45
- 0
ReyMotaAppsDj/reymota/lyrics/forms.py View File

@ -0,0 +1,45 @@
from django import forms
from .models import Artista, Album, Song
class ArtistaForm(forms.ModelForm):
class Meta:
model = Artista
fields = ['nombre', 'biografia', 'foto']
nombre = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}))
biografia = forms.CharField(
widget=forms.TextInput(attrs={'class': 'form-control'}))
class AlbumForm(forms.ModelForm):
class Meta:
model = Album
fields = ['name', 'artist', 'year', 'cover_image']
year = forms.DateField(
widget=forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}))
artist = forms.ModelChoiceField(
queryset=Artista.objects.all(),
widget=forms.Select(attrs={'class': 'form-control'}))
class SongForm(forms.ModelForm):
class Meta:
model = Song
fields = ['title', 'artist', 'album', 'year', 'lyrics']
year = forms.DateField(
widget=forms.DateInput(attrs={'type': 'date', 'class': 'form-control'}))
artist = forms.ModelChoiceField(
queryset=Artista.objects.all(),
widget=forms.Select(attrs={'class': 'form-control'}))
album = forms.ModelChoiceField(
queryset=Album.objects.all(), # habría que seleccionar los álbumes del artista
widget=forms.Select(attrs={'class': 'form-control'}))

+ 52
- 0
ReyMotaAppsDj/reymota/lyrics/migrations/0001_initial.py View File

@ -0,0 +1,52 @@
# Generated by Django 4.2 on 2024-09-10 13:23
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import lyrics.models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Album',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200)),
('year', models.PositiveBigIntegerField(default=2024, validators=[django.core.validators.MinValueValidator(1984), lyrics.models.max_value_current_year])),
('cover_image', models.ImageField(blank=True, null=True, upload_to='cover_image/')),
],
),
migrations.CreateModel(
name='Artista',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('nombre', models.CharField(max_length=200)),
('biografia', models.TextField(blank=True, null=True)),
('foto', models.ImageField(blank=True, null=True, upload_to='artistas/')),
],
),
migrations.CreateModel(
name='Song',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=200)),
('year', models.PositiveBigIntegerField(default=2024, validators=[django.core.validators.MinValueValidator(1984), lyrics.models.max_value_current_year])),
('lyrics', models.CharField(max_length=1000)),
('pista', models.DecimalField(blank=True, decimal_places=0, max_digits=5, null=True)),
('album', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lyrics.album')),
('artist', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lyrics.artista')),
],
),
migrations.AddField(
model_name='album',
name='artist',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='lyrics.artista'),
),
]

+ 42
- 1
ReyMotaAppsDj/reymota/lyrics/models.py View File

@ -1,3 +1,44 @@
from django.db import models
import datetime
from django.core.validators import MaxValueValidator, MinValueValidator
from django.utils.translation import gettext_lazy as _
def current_year():
return datetime.date.today().year
def max_value_current_year(value):
return MaxValueValidator(current_year())(value)
class Artista(models.Model):
nombre = models.CharField(max_length=200)
biografia = models.TextField(blank=True, null=True)
foto = models.ImageField(upload_to='artistas/', blank=True, null=True) # Nuevo campo
def __str__(self):
return self.nombre
class Album(models.Model):
name = models.CharField(max_length=200)
artist = models.ForeignKey(Artista, on_delete=models.CASCADE)
year = models.PositiveBigIntegerField(default=current_year(), validators=[MinValueValidator(1984), max_value_current_year])
cover_image = models.ImageField(upload_to='cover_image/', blank=True, null=True) # Nuevo campo
def __str__(self):
return self.name
class Song(models.Model):
title = models.CharField(max_length=200)
artist = models.ForeignKey(Artista, on_delete=models.CASCADE)
album = models.ForeignKey(Album, on_delete=models.CASCADE)
year = models.PositiveBigIntegerField(default=current_year(), validators=[MinValueValidator(1984), max_value_current_year])
lyrics = models.CharField(max_length=1000)
pista = models.DecimalField(max_digits=5, decimal_places=0, blank=True, null=True)
def __str__(self):
return self.title
# Create your models here.

+ 27
- 0
ReyMotaAppsDj/reymota/lyrics/urls.py View File

@ -0,0 +1,27 @@
from django.urls import path
from . import views
app_name='lyrics'
urlpatterns = [
path('', views.principal, name='principal'),
path('artistas/', views.lista_artistas, name='lista_artistas'),
path('artistas/nuevo/', views.nuevo_artista, name='nuevo_artista'),
path('artistas/<int:artista_id>/', views.detalle_artista, name='detalle_artista'),
path('artistas/<int:artista_id>/editar/', views.editar_artista, name='editar_artista'),
path('artistas/<int:artista_id>/eliminar/', views.eliminar_artista, name='eliminar_artista'),
path('album/', views.lista_albumes, name='lista_albumes'),
path('album/nuevo/', views.nuevo_album, name='nuevo_album'),
path('album/<int:album_id>/', views.detalle_album, name='detalle_album'),
path('album/<int:album_id>/editar/', views.editar_album, name='editar_album'),
path('album/<int:album_id>/eliminar/', views.eliminar_album, name='eliminar_album'),
path('song/', views.lista_songs, name='lista_songs'),
path('song/nuevo/', views.nuevo_song, name='nuevo_song'),
path('song/<int:song_id>/', views.detalle_song, name='detalle_song'),
path('song/<int:song_id>/editar/', views.editar_song, name='editar_song'),
path('song/<int:song_id>/eliminar/', views.eliminar_song, name='eliminar_song'),
]

+ 195
- 2
ReyMotaAppsDj/reymota/lyrics/views.py View File

@ -1,3 +1,196 @@
from django.shortcuts import render
# Create your views here.
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from .models import Artista, Album, Song
from .forms import ArtistaForm, AlbumForm, SongForm
@login_required
def principal(request):
artistas = Artista.objects.all()
albumes = Album.objects.all()
return render(request, 'lyrics/index.html', {'artistas': artistas, 'albumes': albumes})
#########################
# Vistas para los artistas
@login_required
def lista_artistas(request):
artistas = Artista.objects.all()
return render(request, 'lyrics/lista_artistas.html', {'artistas': artistas})
@login_required
def detalle_artista(request, artista_id):
artista = get_object_or_404(Artista, pk=artista_id)
albumes = Album.objects.filter(artista=artista_id)
return render(request, 'lyrics/detalle_artista.html', {'artista': artista, 'albumes': albumes})
@login_required
def nuevo_artista(request):
if request.method == 'POST':
form = ArtistaForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('lyrics:lista_artistas')
else:
form = ArtistaForm()
return render(request, 'lyrics/form_artista.html', {'form': form})
@login_required
def editar_artista(request, artista_id):
artista = get_object_or_404(Artista, pk=artista_id)
if request.method == 'POST':
form = ArtistaForm(request.POST, request.FILES, instance=artista)
if form.is_valid():
form.save()
return redirect('lyrics:lista_artistas')
else:
form = ArtistaForm(instance=artista)
return render(request, 'lyrics/form_artista.html', {'form': form})
@login_required
def eliminar_artista(request, artista_id):
artista = get_object_or_404(Artista, pk=artista_id)
artista.delete()
return redirect('lyrics:lista_artistas')
#########################
# Vistas para los albumes
@login_required
def lista_albumes(request):
albumes = Album.objects.all()
return render(request, 'lyrics/lista_albumes.html', {'albumes': albumes})
@login_required
def detalle_album(request, album_id):
album = get_object_or_404(Album, pk=album_id)
return render(request, 'lyrics/detalle_album.html', {'album': album})
@login_required
def nuevo_album(request):
artistas = Artista.objects.all() # vamos a ver si hay vehículos dados de alta
if artistas:
if request.method == 'POST':
form = AlbumForm(request.POST, request.FILES)
if form.is_valid():
instancia = form.save(commit=False)
aplica_descuento = form.cleaned_data['aplica_descuento']
if aplica_descuento:
instancia.descuento = float(instancia.importe) * 0.03
else:
instancia.descuento = 0.0
instancia.importe = float(instancia.importe) - instancia.descuento
if instancia.litros > 0:
instancia.precioxlitro = round(instancia.importe / float(instancia.litros), 2)
else:
instancia.precioxlitro = 0
# lee todos los albumes del vehículo
# albumes = Albums.query.filter_by(artista_id=artista_id).all()
if Album.objects.filter(artista_id=instancia.artista):
albumes = Album.objects.filter(artista_id=instancia.artista).order_by('-fecha')[0]
instancia.kmsrecorridos = instancia.kms - albumes.kms
if instancia.kmsrecorridos > 0:
instancia.consumo = round(instancia.litros * 100 / instancia.kmsrecorridos, 2)
else:
instancia.kmsrecorridos = 0
instancia.consumo = 0
instancia.save()
return redirect('lyrics:lista_albumes')
else:
form = AlbumForm()
return render(request, 'lyrics/form_album.html', {'form': form})
else:
return render(request, 'lyrics/index.html')
@login_required
def editar_album(request, album_id):
album = get_object_or_404(Album, pk=album_id)
if request.method == 'POST':
form = AlbumForm(request.POST, request.FILES, instance=album)
if form.is_valid():
form.save()
return redirect('lyrics:lista_albumes')
else:
form = AlbumForm(instance=album)
return render(request, 'lyrics/form_album.html', {'form': form})
@login_required
def eliminar_album(request, album_id):
album = Album.objects.get(pk=album_id)
album.delete()
return redirect('lyrics:lista_albumes')
#########################
# Vistas para los songs
@login_required
def lista_songs(request):
songs = Song.objects.all()
return render(request, 'lyrics/lista_songs.html', {'songs': songs})
@login_required
def detalle_song(request, song_id):
song = get_object_or_404(Song, pk=song_id)
albumes = Album.objects.filter(song=song_id)
return render(request, 'lyrics/detalle_song.html', {'song': song, 'albumes': albumes})
@login_required
def nuevo_song(request):
if request.method == 'POST':
form = SongForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return redirect('lyrics:lista_songs')
else:
form = SongForm()
return render(request, 'lyrics/form_song.html', {'form': form})
@login_required
def editar_song(request, song_id):
song = get_object_or_404(Song, pk=song_id)
if request.method == 'POST':
form = SongForm(request.POST, request.FILES, instance=song)
if form.is_valid():
form.save()
return redirect('lyrics:lista_songs')
else:
form = SongForm(instance=song)
return render(request, 'lyrics/form_song.html', {'form': form})
@login_required
def eliminar_song(request, song_id):
song = get_object_or_404(Song, pk=song_id)
song.delete()
return redirect('lyrics:lista_songs')

+ 1
- 0
ReyMotaAppsDj/reymota/reymota/settings.py View File

@ -42,6 +42,7 @@ INSTALLED_APPS = [
'repostajes',
'libros',
'reymotausers',
'lyrics',
]
MIDDLEWARE = [


+ 2
- 0
ReyMotaAppsDj/reymota/reymota/urls.py View File

@ -27,6 +27,8 @@ urlpatterns = [
path('repostajes/', include('repostajes.urls')),
path('lyrics/', include('lyrics.urls')),
path("accounts/", include("accounts.urls")), # new
path("accounts/", include("django.contrib.auth.urls")),


+ 2
- 1
ReyMotaAppsDj/reymota/templates/_cabecera.html View File

@ -97,7 +97,8 @@
<div id="submenu-1" class="collapse submenu submenu-1" data-bs-parent="#menu-accordion">
<ul class="submenu-list list-unstyled">
<li class="submenu-item"><a class="submenu-link" href="{% url 'libros:principal' %}">Libros</a></li>
<li class="submenu-item"><a class="submenu-link" href="{% url 'repostajes:principal' %}">Vehiculos</a></li>
<li class="submenu-item"><a class="submenu-link" href="{% url 'repostajes:principal' %}">Vehículos</a></li>
<li class="submenu-item"><a class="submenu-link" href="{% url 'lyrics:principal' %}">Letras</a></li>
</ul>
</div>
</li><!--//nav-item-->


+ 24
- 0
ReyMotaAppsDj/reymota/templates/lyrics/detalle_album.html View File

@ -0,0 +1,24 @@
{% extends 'base.html' %}
{% block content %}
<div class="container-xl">
<div class="app-card app-card-notification shadow-sm mb-4">
<div class="app-card-header px-4 py-3">
<div class="row g-3 align-items-center">
<div class="col-12 col-lg-auto text-center text-lg-start">
<h4 class="notification-title mb-1">{{ album.name }}</h4>
<ul class="notification-meta list-inline mb-0">
<li class="list-inline-item"><a href="{% url 'lyrics:detalle_album' album.album_id %}">{{ album.album.name }}</a></li>
<li class="list-inline-item">|</li>
<li class="list-inline-item">{{ album.artist }}</li>
<li class="list-inline-item">|</li>
<li class="list-inline-item">{{ album.year }}</li>
</ul>
</div><!--//col-->
</tr>
</div><!--//row-->
</div><!--//app-card-header-->
</div><!--//app-card-->
{% endblock %}

+ 62
- 0
ReyMotaAppsDj/reymota/templates/lyrics/detalle_artista.html View File

@ -0,0 +1,62 @@
{% extends 'base.html' %}
{% block content %}
<div class="container-xl">
<div class="app-card app-card-notification shadow-sm mb-4">
<div class="app-card-header px-4 py-3">
<div class="row g-3 align-items-center">
<div class="col-12 col-lg-auto text-center text-lg-start">
{% if artista.foto %}
<p><img src="{{ artista.foto.url }}" alt="{{ artista.nombre}}" style="width:200px;height:200px;"></p>
{% else %}
<p>No hay imágen disponible</p>
{% endif %}
</div>
<div class="col-12 col-lg-auto text-center text-lg-start">
<h4>{{ artista.nombre }}</h4>
<ul class="notification-meta list-inline mb-0">
<li class="list-inline-item">{{ artista.nombre }}</li>
</ul>
</div>
</div>
</div>
<div class="app-card-body p-4">
{% if albumes %}
<table class="table app-table-hover mb-0 text-left">
<thead>
<tr>
<th class="cell">Título</th>
<th class="cell">Artista</th>
<th class="cell">Year</th>
</tr>
</thead>
<tbody>
{% for album in albumes %}
<tr>
<td class="cell"><a href="{% url 'lyrics:detalle_album' album.id %}">{{ album.name }}</a></td>
<td class="cell">{{ album.artist }}</td>
<td class="cell">{{ album.year }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>No se han encontrado albums para este artista</p>
{% endif %}
</div>
</div>
<div class="row g-3 mb-4 align-items-center justify-content-between">
<div class="col-auto">
<a class="btn app-btn-secondary" href="{% url 'lyrics:lista_albumes' %}">Volver al inicio</a>
</div>
<div class="col-auto">
<a class="btn app-btn-primary" href="{% url 'lyrics:nuevo_album' %}">Añadir album</a> <!-- Faltaría poner el id del artista-->
</div>
</div>
</div>
{% endblock %}

+ 32
- 0
ReyMotaAppsDj/reymota/templates/lyrics/detalle_song.html View File

@ -0,0 +1,32 @@
{% extends 'base.html' %}
{% block content %}
<div class="container-xl">
<div class="app-card app-card-notification shadow-sm mb-4">
<div class="app-card-header px-4 py-3">
<div class="row g-3 align-items-center">
<div class="col-12 col-lg-auto text-center text-lg-start">
<h4 class="notification-title mb-1">{{ repostaje.fecha }}</h4>
<ul class="notification-meta list-inline mb-0">
<li class="list-inline-item"><a href="{% url 'repostajes:detalle_vehiculo' repostaje.vehiculo_id %}">{{ repostaje.vehiculo.matricula }}</a></li>
<li class="list-inline-item">|</li>
<li class="list-inline-item">{{ repostaje.kms }} kms</li>
<li class="list-inline-item">|</li>
<li class="list-inline-item">{{ repostaje.litros }} litros</li>
<li class="list-inline-item">|</li>
<li class="list-inline-item">{{ repostaje.importe }} €</li>
<li class="list-inline-item">|</li>
<li class="list-inline-item">{{ repostaje.kmsrecorridos }} kms. recorridos</li>
<li class="list-inline-item">|</li>
<li class="list-inline-item">{{ repostaje.consumo }} litros/100 kms</li>
<li class="list-inline-item">|</li>
<li class="list-inline-item">{{ repostaje.precioxlitro }} €/litros</li>
</ul>
</div><!--//col-->
</tr>
</div><!--//row-->
</div><!--//app-card-header-->
</div><!--//app-card-->
{% endblock %}

+ 17
- 0
ReyMotaAppsDj/reymota/templates/lyrics/form_album.html View File

@ -0,0 +1,17 @@
{% extends 'base.html' %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3>{% if form.instance.pk %}Editar álbum{% else %}Nuevo álbum{% endif %}</h3>
<div class="box">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="text mb-3">
<button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Guardar</button>
</div>
</form>
{{ form.media }}
</div>
</div>
{% endblock %}

+ 17
- 0
ReyMotaAppsDj/reymota/templates/lyrics/form_artista.html View File

@ -0,0 +1,17 @@
{% extends 'base.html' %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3>{% if form.instance.pk %}Editar artista{% else %}Nuevo artista{% endif %}</h3>
<div class="box">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="text mb-3">
<button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Guardar</button>
</div>
</form>
</div>
</div>
{% endblock %}

+ 17
- 0
ReyMotaAppsDj/reymota/templates/lyrics/form_song.html View File

@ -0,0 +1,17 @@
{% extends 'base.html' %}
{% block content %}
<div class="column is-4 is-offset-4">
<h3>{% if form.instance.pk %}Editar repostaje{% else %}Nuevo repostaje{% endif %}</h3>
<div class="box">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<div class="text mb-3">
<button type="submit" class="btn app-btn-primary w-100 theme-btn mx-auto">Guardar</button>
</div>
</form>
{{ form.media }}
</div>
</div>
{% endblock %}

+ 64
- 0
ReyMotaAppsDj/reymota/templates/lyrics/index.html View File

@ -0,0 +1,64 @@
{% extends 'base.html' %}
{% block content %}
<div class="container-xl">
<h1 class="app-page-title">Introducción</h1>
<div class="app-card alert alert-dismissible shadow-sm mb-4 border-left-decoration" role="alert">
<div class="inner">
<div class="app-card-body p-3 p-lg-4">
<h3 class="mb-3">¡Bienvenido a la gestión de letras!</h3>
<div class="row gx-5 gy-3">
<!--
<div class="col-12 col-lg-9">
<div>Pensado inicialmente para guardar las letras de las canciones de Bruce Springsteen.</div>
</div>--><!--//col-->
</div><!--//row-->
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div><!--//app-card-body-->
</div><!--//inner-->
</div><!--//app-card-->
<div class="row g-4 mb-4">
<div class="col-lg-4 col-md-6 d-flex align-items-stretch mt-4 mt-lg-0" data-aos="zoom-in" data-aos-delay="300">
<div class="icon-box iconbox-pink">
<div class="icon">
<svg width="100" height="100" viewBox="0 0 600 600" xmlns="http://www.w3.org/2000/svg">
<path stroke="none" stroke-width="0" fill="#f5f5f5" d="M300,541.5067337569781C382.14930387511276,545.0595476570109,479.8736841581634,548.3450877840088,526.4010558755058,480.5488172755941C571.5218469581645,414.80211281144784,517.5187510058486,332.0715597781072,496.52539010469104,255.14436215662573C477.37192572678356,184.95920475031193,473.57363656557914,105.61284051026155,413.0603344069578,65.22779650032875C343.27470386102294,18.654635553484475,251.2091493199835,5.337323636656869,175.0934190732945,40.62881213300186C97.87086631185822,76.43348514350839,51.98124368387456,156.15599469081315,36.44837278890362,239.84606092416172C21.716077023791087,319.22268207091537,43.775223500013084,401.1760424656574,96.891909868211,461.97329694683043C147.22146801428983,519.5804099606455,223.5754009179313,538.201503339737,300,541.5067337569781"></path>
</svg>
<i class='bx bx-bowl-hot'></i>
</div>
<h4><a href="{% url 'lyrics:lista_artistas' %}">Artistas</a></h4>
<p>Listado de vehículoss</p>
</div>
<div class="icon-box iconbox-pink">
<div class="icon">
<svg width="100" height="100" viewBox="0 0 600 600" xmlns="http://www.w3.org/2000/svg">
<path stroke="none" stroke-width="0" fill="#f5f5f5" d="M300,541.5067337569781C382.14930387511276,545.0595476570109,479.8736841581634,548.3450877840088,526.4010558755058,480.5488172755941C571.5218469581645,414.80211281144784,517.5187510058486,332.0715597781072,496.52539010469104,255.14436215662573C477.37192572678356,184.95920475031193,473.57363656557914,105.61284051026155,413.0603344069578,65.22779650032875C343.27470386102294,18.654635553484475,251.2091493199835,5.337323636656869,175.0934190732945,40.62881213300186C97.87086631185822,76.43348514350839,51.98124368387456,156.15599469081315,36.44837278890362,239.84606092416172C21.716077023791087,319.22268207091537,43.775223500013084,401.1760424656574,96.891909868211,461.97329694683043C147.22146801428983,519.5804099606455,223.5754009179313,538.201503339737,300,541.5067337569781"></path>
</svg>
<i class='bx bx-bowl-hot'></i>
</div>
<h4><a href="{% url 'lyrics:lista_albumes' %}">Álbumes</a></h4>
<p>Relación de repostajes</p>
</div>
<div class="icon-box iconbox-pink">
<div class="icon">
<svg width="100" height="100" viewBox="0 0 600 600" xmlns="http://www.w3.org/2000/svg">
<path stroke="none" stroke-width="0" fill="#f5f5f5" d="M300,541.5067337569781C382.14930387511276,545.0595476570109,479.8736841581634,548.3450877840088,526.4010558755058,480.5488172755941C571.5218469581645,414.80211281144784,517.5187510058486,332.0715597781072,496.52539010469104,255.14436215662573C477.37192572678356,184.95920475031193,473.57363656557914,105.61284051026155,413.0603344069578,65.22779650032875C343.27470386102294,18.654635553484475,251.2091493199835,5.337323636656869,175.0934190732945,40.62881213300186C97.87086631185822,76.43348514350839,51.98124368387456,156.15599469081315,36.44837278890362,239.84606092416172C21.716077023791087,319.22268207091537,43.775223500013084,401.1760424656574,96.891909868211,461.97329694683043C147.22146801428983,519.5804099606455,223.5754009179313,538.201503339737,300,541.5067337569781"></path>
</svg>
<i class='bx bx-bowl-hot'></i>
</div>
<h4><a href="{% url 'lyrics:lista_songs' %}">Canciones</a></h4>
<p>Listado de vehículoss</p>
</div>
</div>
</div><!--//row-->
</div><!--//container-fluid-->
{% endblock %}

+ 57
- 0
ReyMotaAppsDj/reymota/templates/lyrics/lista_albumes.html View File

@ -0,0 +1,57 @@
{% extends 'base.html' %}
{% block content %}
<div class="container-xl">
<div class="row g-3 mb-4 align-items-center justify-content-between">
<div class="col-auto">
<h1 class="app-page-title mb-0">Álbumes</h1>
</div>
</div><!--//row-->
<div class="col-auto">
<div class="page-utilities">
<div class="row g-4 justify-content-start justify-content-md-end align-items-center">
<div class="col-auto">
<a class="btn app-btn-primary" href="{% url 'lyrics:nuevo_album' %}">Añadir álbum</a>
</div>
</div><!--//row-->
</div><!--//table-utilities-->
</div><!--//col-auto-->
<div class="app-card app-card-notification shadow-sm mb-4">
<div class="app-card-body p-4">
<table class="table app-table-hover mb-0 text-left">
<thead>
<tr>
<th class="cell">Fecha</th>
<th class="cell">Vehículo</th>
<th class="cell">Kilómetros</th>
<th class="cell">Litros</th>
<th class="cell">Importe</th>
<th class="cell">Descuento</th>
<th class="cell">Precio por litro</th>
<th class="cell">Kms recorridos</th>
<th class="cell">Consumo/100 kms</th>
</tr>
</thead>
{% for repostaje in repostajes %}
<tbody>
<tr>
<td class="cell"><a href="{% url 'repostajes:detalle_repostaje' repostaje.id %}">{{ repostaje.fecha }}</a></td>
<td class="cell"><a href="{% url 'repostajes:detalle_vehiculo' repostaje.vehiculo.id %}">{{ repostaje.vehiculo.matricula }}</a></td>
<td class="cell">{{ repostaje.kms }}</td>
<td class="cell">{{ repostaje.litros }}</td>
<td class="cell">{{ repostaje.importe }} €</td>
<td class="cell">{{ repostaje.descuento }} €</td>
<td class="cell">{{ repostaje.precioxlitro }} €</td>
<td class="cell">{{ repostaje.kmsrecorridos }}</td>
<td class="cell">{{ repostaje.consumo }}</td>
</tr>
</tbody>
{% endfor %}
</table>
</div>
</div><!--//container-fluid-->
{% endblock %}

+ 65
- 0
ReyMotaAppsDj/reymota/templates/lyrics/lista_artistas.html View File

@ -0,0 +1,65 @@
{% extends 'base.html' %}
{% block content %}
<div class="container-xl">
<div class="row g-3 mb-4 align-items-center justify-content-between">
<div class="col-auto">
<h1 class="app-page-title mb-0">Artistas</h1>
</div>
</div><!--//row-->
<div class="col-auto">
<div class="page-utilities">
<div class="row g-4 justify-content-start justify-content-md-end align-items-center">
<div class="col-auto">
<a class="btn app-btn-primary" href="{% url 'lyrics:nuevo_artista' %}">Añadir artista</a>
</div>
</div><!--//row-->
</div><!--//table-utilities-->
</div><!--//col-auto-->
<div class="row g-4">
{% for artista in artistas %}
<div class="col-6 col-md-4 col-xl-3 col-xxl-2">
<div class="app-card app-card-doc shadow-sm h-100">
<div class="app-card-body p-3 has-card-actions">
{% if artista.foto %}
<img src="{{ artista.foto.url }}" alt="Foto del artista" style="width:200px;height:200px;">
{% else %}
Sin imágen
{% endif %}
<h4 class="app-doc-title truncate mb-0"><a href="{% url 'lyrics:detalle_artista' artista.id %}">{{ artista.matricula}}</a></h4>
<div class="app-card-actions">
<div class="dropdown">
<div class="dropdown-toggle no-toggle-arrow" data-bs-toggle="dropdown" aria-expanded="false">
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-three-dots-vertical" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
</svg>
</div><!--//dropdown-toggle-->
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'lyrics:detalle_artista' artista.id %}"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-eye me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.134 13.134 0 0 0 1.66 2.043C4.12 11.332 5.88 12.5 8 12.5c2.12 0 3.879-1.168 5.168-2.457A13.134 13.134 0 0 0 14.828 8a13.133 13.133 0 0 0-1.66-2.043C11.879 4.668 10.119 3.5 8 3.5c-2.12 0-3.879 1.168-5.168 2.457A13.133 13.133 0 0 0 1.172 8z"/>
<path fill-rule="evenodd" d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
</svg>Ver</a></li>
<li><a class="dropdown-item" href="{% url 'lyrics:editar_artista' artista.id %}"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-pencil me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168l10-10zM11.207 2.5L13.5 4.793 14.793 3.5 12.5 1.207 11.207 2.5zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293l6.5-6.5zm-9.761 5.175l-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325z"/>
</svg>Editar</a></li>
<li><a class="dropdown-item" href="{% url 'lyrics:eliminar_artista' artista.id %}"><svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-download me-2" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M.5 9.9a.5.5 0 0 1 .5.5v2.5a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-2.5a.5.5 0 0 1 1 0v2.5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2v-2.5a.5.5 0 0 1 .5-.5z"/>
<path fill-rule="evenodd" d="M7.646 11.854a.5.5 0 0 0 .708 0l3-3a.5.5 0 0 0-.708-.708L8.5 10.293V1.5a.5.5 0 0 0-1 0v8.793L5.354 8.146a.5.5 0 1 0-.708.708l3 3z"/>
</svg>Eliminar</a></li>
<!--
</ul>
</div><!--//dropdown-->
</div><!--//app-card-actions-->
</div><!--//app-card-body-->
</div>
</div>
{% endfor %}
</div>
</div><!--//container-fluid-->
{% endblock %}

+ 57
- 0
ReyMotaAppsDj/reymota/templates/lyrics/lista_songs.html View File

@ -0,0 +1,57 @@
{% extends 'base.html' %}
{% block content %}
<div class="container-xl">
<div class="row g-3 mb-4 align-items-center justify-content-between">
<div class="col-auto">
<h1 class="app-page-title mb-0">Repostajes</h1>
</div>
</div><!--//row-->
<div class="col-auto">
<div class="page-utilities">
<div class="row g-4 justify-content-start justify-content-md-end align-items-center">
<div class="col-auto">
<a class="btn app-btn-primary" href="{% url 'repostajes:nuevo_repostaje' %}">Añadir repostaje</a>
</div>
</div><!--//row-->
</div><!--//table-utilities-->
</div><!--//col-auto-->
<div class="app-card app-card-notification shadow-sm mb-4">
<div class="app-card-body p-4">
<table class="table app-table-hover mb-0 text-left">
<thead>
<tr>
<th class="cell">Fecha</th>
<th class="cell">Vehículo</th>
<th class="cell">Kilómetros</th>
<th class="cell">Litros</th>
<th class="cell">Importe</th>
<th class="cell">Descuento</th>
<th class="cell">Precio por litro</th>
<th class="cell">Kms recorridos</th>
<th class="cell">Consumo/100 kms</th>
</tr>
</thead>
{% for repostaje in repostajes %}
<tbody>
<tr>
<td class="cell"><a href="{% url 'repostajes:detalle_repostaje' repostaje.id %}">{{ repostaje.fecha }}</a></td>
<td class="cell"><a href="{% url 'repostajes:detalle_vehiculo' repostaje.vehiculo.id %}">{{ repostaje.vehiculo.matricula }}</a></td>
<td class="cell">{{ repostaje.kms }}</td>
<td class="cell">{{ repostaje.litros }}</td>
<td class="cell">{{ repostaje.importe }} €</td>
<td class="cell">{{ repostaje.descuento }} €</td>
<td class="cell">{{ repostaje.precioxlitro }} €</td>
<td class="cell">{{ repostaje.kmsrecorridos }}</td>
<td class="cell">{{ repostaje.consumo }}</td>
</tr>
</tbody>
{% endfor %}
</table>
</div>
</div><!--//container-fluid-->
{% endblock %}

Loading…
Cancel
Save