diff --git a/altessimo/settings.py b/altessimo/settings.py index 1920139..320e65e 100644 --- a/altessimo/settings.py +++ b/altessimo/settings.py @@ -39,6 +39,7 @@ INSTALLED_APPS = [ 'django.contrib.staticfiles', 'categories', 'artists', + 'idols', 'songs', 'home', ] diff --git a/altessimo/urls.py b/altessimo/urls.py index fbc2d75..14c5bbc 100644 --- a/altessimo/urls.py +++ b/altessimo/urls.py @@ -21,5 +21,6 @@ urlpatterns = [ path('taxonomy/', include('categories.urls')), path('artists/', include('artists.urls')), path('songs/', include('songs.urls')), + path('idols/', include('idols.urls')), path('admin/', admin.site.urls), ] diff --git a/artists/migrations/0005_idol_voiceactor.py b/artists/migrations/0005_idol_voiceactor.py new file mode 100644 index 0000000..9c8c779 --- /dev/null +++ b/artists/migrations/0005_idol_voiceactor.py @@ -0,0 +1,31 @@ +# Generated by Django 3.2.5 on 2021-07-09 17:06 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('artists', '0004_auto_20201216_1633'), + ] + + operations = [ + migrations.CreateModel( + name='VoiceActor', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=255)), + ('romanized_name', models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name='Idol', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=255)), + ('romanized_name', models.CharField(max_length=255)), + ('voice_actor', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='artists.voiceactor')), + ], + ), + ] diff --git a/artists/migrations/0006_auto_20210709_1720.py b/artists/migrations/0006_auto_20210709_1720.py new file mode 100644 index 0000000..d21901a --- /dev/null +++ b/artists/migrations/0006_auto_20210709_1720.py @@ -0,0 +1,20 @@ +# Generated by Django 3.2.5 on 2021-07-09 17:20 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('songs', '0006_alter_song_idols'), + ('artists', '0005_idol_voiceactor'), + ] + + operations = [ + migrations.DeleteModel( + name='Idol', + ), + migrations.DeleteModel( + name='VoiceActor', + ), + ] diff --git a/artists/models.py b/artists/models.py index 316f70c..db16da9 100644 --- a/artists/models.py +++ b/artists/models.py @@ -34,3 +34,4 @@ class Artist(models.Model): def save(self, *args, **kwargs): self.slug = slugify(self.romanized_name) super().save(*args,**kwargs) + diff --git a/artists/views.py b/artists/views.py index b84f39d..66e75c9 100644 --- a/artists/views.py +++ b/artists/views.py @@ -4,24 +4,30 @@ from django.shortcuts import render from .models import Artist from songs.models import OutsideSong + def artist_index(request): artists = Artist.objects.all() objs = {} if "q" in request.GET: q = request.GET['q'] - artists = Artist.objects.filter(name__icontains=q) | Artist.objects.filter(romanized_name__icontains=q) + artists = Artist.objects.filter( + name__icontains=q) | Artist.objects.filter(romanized_name__icontains=q) objs['q'] = q objs['artists'] = artists - return render(request,'artists/index.html',objs) + return render(request, 'artists/index.html', objs) + def artist_show(request, slug): artist = Artist.objects.filter(slug=slug)[0] - credit_songs = artist.written_songs.all() | artist.composed_songs.all() | artist.arranged_songs.all() + credit_songs = artist.written_songs.all( + ) | artist.composed_songs.all() | artist.arranged_songs.all() aliases = artist.aliases.all() outside_songs = OutsideSong.objects.filter(composer=artist) for alias in aliases: - credit_songs = credit_songs | alias.written_songs.all() | artist.composed_songs.all() | artist.arranged_songs.all() - outside_songs = outside_songs | OutsideSong.objects.filter(composer=alias) + credit_songs = credit_songs | alias.written_songs.all( + ) | artist.composed_songs.all() | artist.arranged_songs.all() + outside_songs = outside_songs | OutsideSong.objects.filter( + composer=alias) credit_songs = credit_songs.distinct() outside_songs = outside_songs.distinct() - return render(request,'artists/show.html',{'artist': artist,'credit_songs':credit_songs,'outside_songs':outside_songs}) \ No newline at end of file + return render(request, 'artists/show.html', {'artist': artist, 'credit_songs': credit_songs, 'outside_songs': outside_songs}) \ No newline at end of file diff --git a/idols/__init__.py b/idols/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/idols/admin.py b/idols/admin.py new file mode 100644 index 0000000..2c672ba --- /dev/null +++ b/idols/admin.py @@ -0,0 +1,6 @@ +from idols.models import Idol +from django.contrib import admin + +# Register your models here. + +admin.site.register(Idol) \ No newline at end of file diff --git a/idols/apps.py b/idols/apps.py new file mode 100644 index 0000000..9d222f7 --- /dev/null +++ b/idols/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class IdolsConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'idols' diff --git a/idols/migrations/0001_initial.py b/idols/migrations/0001_initial.py new file mode 100644 index 0000000..7582104 --- /dev/null +++ b/idols/migrations/0001_initial.py @@ -0,0 +1,32 @@ +# Generated by Django 3.2.5 on 2021-07-09 17:20 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='VoiceActor', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=255)), + ('romanized_name', models.CharField(max_length=255)), + ], + ), + migrations.CreateModel( + name='Idol', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(blank=True, max_length=255)), + ('romanized_name', models.CharField(max_length=255)), + ('voice_actor', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='idols.voiceactor')), + ], + ), + ] diff --git a/idols/migrations/0002_auto_20210709_1733.py b/idols/migrations/0002_auto_20210709_1733.py new file mode 100644 index 0000000..4f0ecc8 --- /dev/null +++ b/idols/migrations/0002_auto_20210709_1733.py @@ -0,0 +1,27 @@ +# Generated by Django 3.2.5 on 2021-07-09 17:33 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('idols', '0001_initial'), + ] + + operations = [ + migrations.RemoveField( + model_name='idol', + name='voice_actor', + ), + migrations.AddField( + model_name='idol', + name='romanized_voice_actor_name', + field=models.CharField(blank=True, max_length=255), + ), + migrations.AddField( + model_name='idol', + name='voice_actor_name', + field=models.CharField(blank=True, max_length=255), + ), + ] diff --git a/idols/migrations/0003_auto_20210709_1803.py b/idols/migrations/0003_auto_20210709_1803.py new file mode 100644 index 0000000..4349955 --- /dev/null +++ b/idols/migrations/0003_auto_20210709_1803.py @@ -0,0 +1,24 @@ +# Generated by Django 3.2.5 on 2021-07-09 18:03 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('categories', '0009_auto_20201216_1732'), + ('idols', '0002_auto_20210709_1733'), + ] + + operations = [ + migrations.DeleteModel( + name='VoiceActor', + ), + migrations.AddField( + model_name='idol', + name='branch', + field=models.ForeignKey(default=1, on_delete=django.db.models.deletion.PROTECT, to='categories.branch'), + preserve_default=False, + ), + ] diff --git a/idols/migrations/__init__.py b/idols/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/idols/models.py b/idols/models.py new file mode 100644 index 0000000..45044d5 --- /dev/null +++ b/idols/models.py @@ -0,0 +1,30 @@ +from django.db import models + +# Create your models here. + +# Create your models here. + + +class IdolManager(models.Manager): + def comma_to_qs(self, idols_str): + final_ids = [] + if idols_str: + for idol in idols_str.split(','): + obj, created = self.get_or_create(romanized_name=idol.strip()) + final_ids.append(obj.id) + qs = self.get_queryset().filter(id__in=final_ids).distinct() + return qs + return self.none() + + +class Idol(models.Model): + branch = models.ForeignKey("categories.Branch", on_delete=models.PROTECT) + name = models.CharField(max_length=255, blank=True) + romanized_name = models.CharField(max_length=255) + voice_actor_name = models.CharField(max_length=255, blank=True) + romanized_voice_actor_name = models.CharField(max_length=255, blank=True) + + objects = IdolManager() + + def __str__(self): + return self.romanized_name+" (CV: "+self.romanized_voice_actor_name+")" diff --git a/idols/templates/idols/index.html b/idols/templates/idols/index.html new file mode 100644 index 0000000..5d842c6 --- /dev/null +++ b/idols/templates/idols/index.html @@ -0,0 +1,27 @@ +{% extends 'layouts/base.html' %} + +{% block title %} Idols {% endblock %} + +{% block content %} +

Idols

+
+
+ + +
+
+ + + + + + {% for idol in idols %} + + + + {% endfor %} + +
Idol
+ {{ idol.romanized_name }} +
+{% endblock %} \ No newline at end of file diff --git a/idols/templates/idols/show.html b/idols/templates/idols/show.html new file mode 100644 index 0000000..8b478f7 --- /dev/null +++ b/idols/templates/idols/show.html @@ -0,0 +1,32 @@ +{% extends 'layouts/base.html' %} + +{% block title %} Idol: {{ idol.romanized_name }} {% endblock %} + +{% block content %} +

Idol: {{ idol.romanized_name }}

+

Metadata

+ + + {% if idol.name %} + + + + + {% endif %} + {% if idol.romanized_name %} + + + + + {% endif %} + +
+ Name + + {{ idol.name }} +
+ Romanized Name + + {{ idol.romanized_name }} +
+{% endblock %} \ No newline at end of file diff --git a/idols/tests.py b/idols/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/idols/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/idols/urls.py b/idols/urls.py new file mode 100644 index 0000000..9a327e9 --- /dev/null +++ b/idols/urls.py @@ -0,0 +1,8 @@ +from django.urls import path + +from . import views + +urlpatterns = [ + path('',views.idol_index), + path('',views.idol_show) +] diff --git a/idols/views.py b/idols/views.py new file mode 100644 index 0000000..62287dd --- /dev/null +++ b/idols/views.py @@ -0,0 +1,19 @@ +from idols.models import Idol +from django.shortcuts import render + +# Create your views here. +def idol_index(request): + idols = Idol.objects.all() + objs = {} + if "q" in request.GET: + q = request.GET['q'] + idols = Idol.objects.filter(name__icontains=q) | Idol.objects.filter( + romanized_name__icontains=q) + objs['q'] = q + objs['idols'] = idols + return render(request, 'idols/index.html', objs) + + +def idol_show(request, id): + idol = Idol.objects.filter(id=id)[0] + return render(request, 'idols/show.html', {'idol': idol}) diff --git a/songs/admin.py b/songs/admin.py index 02cacf3..f5357b1 100644 --- a/songs/admin.py +++ b/songs/admin.py @@ -3,11 +3,15 @@ from django.contrib import admin from .models import Song, OutsideSong from artists.models import Artist +from idols.models import Idol + class SongForm(forms.ModelForm): lyricist_str = forms.CharField(label='Lyricists', required=False) composer_str = forms.CharField(label='Composers', required=False) arranger_str = forms.CharField(label='Arrangers', required=False) + idols_str = forms.CharField(label='Idols', required=False) + class Meta: model = Song fields = [ @@ -17,33 +21,44 @@ class SongForm(forms.ModelForm): 'lyricist_str', 'composer_str', 'arranger_str', + 'idols_str', 'impression', ] - + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields['impression'].widget.attrs['class'] = 'tm-textfield' instance = kwargs.get("instance") if instance: - self.fields['lyricist_str'].initial = ', '.join(x.romanized_name for x in instance.lyricist.all() ) - self.fields['composer_str'].initial = ', '.join(x.romanized_name for x in instance.composer.all() ) - self.fields['arranger_str'].initial = ', '.join(x.romanized_name for x in instance.arranger.all() ) + self.fields['lyricist_str'].initial = ', '.join( + x.romanized_name for x in instance.lyricist.all()) + self.fields['composer_str'].initial = ', '.join( + x.romanized_name for x in instance.composer.all()) + self.fields['arranger_str'].initial = ', '.join( + x.romanized_name for x in instance.arranger.all()) + self.fields['idols_str'].initial = ', '.join( + x.romanized_name for x in instance.idols.all()) + class SongAdmin(admin.ModelAdmin): form = SongForm - search_fields = ['romanized_title','title'] + search_fields = ['romanized_title', 'title'] + class Media: js = ( 'https://cdnjs.cloudflare.com/ajax/libs/tinymce/5.6.2/tinymce.min.js', 'tinymce-init.js' ) + def save_model(self, request, obj, form, change): lyricist_str = form.cleaned_data.get('lyricist_str') composer_str = form.cleaned_data.get('composer_str') arranger_str = form.cleaned_data.get('arranger_str') + idols_str = form.cleaned_data.get('idols_str') lyricist = Artist.objects.comma_to_qs(lyricist_str) composer = Artist.objects.comma_to_qs(composer_str) arranger = Artist.objects.comma_to_qs(arranger_str) + idols = Idol.objects.comma_to_qs(idols_str) if not obj.id: obj.save() obj.lyricist.clear() @@ -52,10 +67,14 @@ class SongAdmin(admin.ModelAdmin): obj.composer.add(*composer) obj.arranger.clear() obj.arranger.add(*arranger) + obj.idols.clear() + obj.idols.add(*idols) obj.save() + class OutsideSongAdmin(admin.ModelAdmin): search_fields = ['title'] + admin.site.register(Song, SongAdmin) admin.site.register(OutsideSong, OutsideSongAdmin) diff --git a/songs/migrations/0005_song_idols.py b/songs/migrations/0005_song_idols.py new file mode 100644 index 0000000..df6972f --- /dev/null +++ b/songs/migrations/0005_song_idols.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.5 on 2021-07-09 17:11 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('artists', '0005_idol_voiceactor'), + ('songs', '0004_auto_20201217_0812'), + ] + + operations = [ + migrations.AddField( + model_name='song', + name='idols', + field=models.ManyToManyField(blank=True, related_name='idol_songs', to='artists.Idol'), + ), + ] diff --git a/songs/migrations/0006_alter_song_idols.py b/songs/migrations/0006_alter_song_idols.py new file mode 100644 index 0000000..123ea93 --- /dev/null +++ b/songs/migrations/0006_alter_song_idols.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.5 on 2021-07-09 17:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('idols', '0001_initial'), + ('songs', '0005_song_idols'), + ] + + operations = [ + migrations.AlterField( + model_name='song', + name='idols', + field=models.ManyToManyField(blank=True, related_name='idol_songs', to='idols.Idol'), + ), + ] diff --git a/songs/models.py b/songs/models.py index 88ffdad..8fc67b1 100644 --- a/songs/models.py +++ b/songs/models.py @@ -9,6 +9,7 @@ class Song(models.Model): lyricist = models.ManyToManyField("artists.Artist", blank=True, related_name="written_songs") composer = models.ManyToManyField("artists.Artist", blank=True, related_name="composed_songs") arranger = models.ManyToManyField("artists.Artist", blank=True, related_name="arranged_songs") + idols = models.ManyToManyField("idols.Idol",blank=True,related_name="idol_songs") impression = models.TextField(blank=True) class Meta: