pl:python:dbaudiocd
Różnice
Różnice między wybraną wersją a wersją aktualną.
Poprzednia rewizja po obu stronachPoprzednia wersjaNowa wersja | Poprzednia wersja | ||
pl:python:dbaudiocd [2023/11/23 14:38] – [Modyfikacja formularzy Artist-Song w panelu admin] sindap | pl:python:dbaudiocd [2024/01/05 13:22] (aktualna) – [Modyfikacja w pliku cdacd/cdacd/settings.py] sindap | ||
---|---|---|---|
Linia 76: | Linia 76: | ||
LANGUAGE_CODE = ' | LANGUAGE_CODE = ' | ||
TIME_ZONE = ' | TIME_ZONE = ' | ||
+ | |||
+ | Poniżej przykład struktury pliku '' | ||
+ | |||
+ | <code python apps.py> | ||
+ | from django.apps import AppConfig | ||
+ | |||
+ | |||
+ | class DbcdappConfig(AppConfig): | ||
+ | default_auto_field = ' | ||
+ | name = ' | ||
+ | </ | ||
+ | |||
+ | W tym przykładzie '' | ||
+ | |||
+ | Warto wspomnieć, że w pliku można nadać bardziej ludzką nazwę aplikacji: | ||
+ | |||
+ | <code python apps.py> | ||
+ | from django.apps import AppConfig | ||
+ | |||
+ | |||
+ | class DbcdappConfig(AppConfig): | ||
+ | default_auto_field = ' | ||
+ | name = ' | ||
+ | verbose_name = 'Moja Aplikacja' | ||
+ | </ | ||
===== Pierwsze uruchomienie serwera ===== | ===== Pierwsze uruchomienie serwera ===== | ||
Linia 823: | Linia 848: | ||
</ | </ | ||
- | Dodanie modelu MusicAlbum | + | ===== Dodanie modelu MusicAlbum |
- | następny model będzie zawierał informację o tytule albumu na jakim nośniku został wydany. Model będzie powiązany z modelem Song. Jak już się można domyśleć dany utwór może się znajdować na wielu albumach. Sam utwór będzie taki sam no chyba, że powstanie jego inna wersja ale to już wtedy będzie traktowany jako inny utwór. | + | |
+ | Następny model będzie zawierał informację o tytule albumu, na jakim nośniku został wydany. Model będzie powiązany z modelem | ||
+ | \\ | ||
+ | Analogicznie jak poprzednio musimy użyć relacji wiele-do-wielu. Opcję '' | ||
+ | |||
+ | <code python models.py> | ||
+ | from django.db import models | ||
+ | from django.utils import timezone | ||
+ | from .verbose_names import verbose_names | ||
+ | from django.core.validators import MinValueValidator, | ||
+ | |||
+ | class Song(models.Model): | ||
+ | song_title = models.CharField(max_length=200, | ||
+ | release_year = models.CharField(max_length=4, | ||
+ | duration = models.DurationField(null=True, | ||
+ | created_at = models.DateTimeField(default=timezone.now, | ||
+ | modified_at = models.DateTimeField(auto_now=True, | ||
+ | |||
+ | class Meta: | ||
+ | verbose_name = ' | ||
+ | verbose_name_plural = ' | ||
+ | unique_together = (' | ||
+ | |||
+ | def __str__(self): | ||
+ | return f" | ||
+ | |||
+ | class Artist(models.Model): | ||
+ | artist_name = models.CharField(max_length=255, | ||
+ | songs = models.ManyToManyField(Song) | ||
+ | |||
+ | class Meta: | ||
+ | verbose_name = ' | ||
+ | verbose_name_plural = ' | ||
+ | |||
+ | def __str__(self): | ||
+ | return self.artist_name | ||
+ | |||
+ | class MusicAlbum(models.Model): | ||
+ | MEDIUM_TYPE = ( | ||
+ | (' | ||
+ | (' | ||
+ | (' | ||
+ | ) | ||
+ | album_title = models.CharField(max_length=255, | ||
+ | medium_type = models.CharField(max_length=50, | ||
+ | disc_number = models.PositiveIntegerField( | ||
+ | validators=[MinValueValidator(1), | ||
+ | MaxValueValidator(50)], | ||
+ | ) | ||
+ | total_disc = models.PositiveIntegerField( | ||
+ | validators=[MinValueValidator(1), | ||
+ | MaxValueValidator(50)], | ||
+ | ) | ||
+ | songs = models.ManyToManyField(Song) | ||
+ | |||
+ | def __str__(self): | ||
+ | return f" | ||
+ | |||
+ | def clean(self): | ||
+ | if self.disc_number and self.total_disc and self.disc_number > self.total_disc: | ||
+ | raise ValidationError(" | ||
+ | </ | ||
+ | |||
+ | ===== Dodanie MusicAlbum w panelu admina ===== | ||
+ | |||
+ | <code python admin.py> | ||
+ | from django.contrib import admin | ||
+ | from .models import Song, Artist, MusicAlbum | ||
+ | from django import forms | ||
+ | |||
+ | class SongAdminForm(forms.ModelForm): | ||
+ | class Meta: | ||
+ | model = Song | ||
+ | fields = [' | ||
+ | |||
+ | def __init__(self, | ||
+ | super().__init__(*args, | ||
+ | |||
+ | # Dodaj placeholder do pola duration | ||
+ | self.fields[' | ||
+ | |||
+ | # Dodaj placeholder do pola rok | ||
+ | self.fields[' | ||
+ | |||
+ | def clean_release_year(self): | ||
+ | release_year = self.cleaned_data[' | ||
+ | |||
+ | # Sprawdź, czy rok wydania zawiera dokładnie cztery cyfry | ||
+ | if release_year and (len(str(release_year)) != 4 or not str(release_year).isdigit()): | ||
+ | raise forms.ValidationError(' | ||
+ | |||
+ | # Sprawdź, czy rok wydania nie jest większy niż rok utworzenia | ||
+ | if release_year: | ||
+ | created_at_year = self.instance.created_at.year if self.instance and self.instance.created_at else timezone.now().year | ||
+ | if int(release_year) > created_at_year: | ||
+ | raise forms.ValidationError(" | ||
+ | |||
+ | return release_year | ||
+ | |||
+ | def clean_duration(self): | ||
+ | duration = self.cleaned_data[' | ||
+ | |||
+ | # Sprawdzamy, czy duration ma poprawny format (HH: | ||
+ | if duration.total_seconds() < 0: | ||
+ | raise forms.ValidationError(' | ||
+ | |||
+ | # Sprawdzamy, czy duration nie przekracza 01:59:59 | ||
+ | if duration.total_seconds() > 7199: | ||
+ | raise forms.ValidationError(' | ||
+ | |||
+ | return duration | ||
+ | |||
+ | class ArtistInline(admin.TabularInline): | ||
+ | model = Artist.songs.through | ||
+ | extra = 1 | ||
+ | |||
+ | @admin.register(Song) | ||
+ | class SongAdmin(admin.ModelAdmin): | ||
+ | form = SongAdminForm | ||
+ | list_display = (' | ||
+ | list_filter = (' | ||
+ | search_fields = (' | ||
+ | readonly_fields = [' | ||
+ | inlines = [ArtistInline] | ||
+ | |||
+ | @admin.register(Artist) | ||
+ | class ArtistAdmin(admin.ModelAdmin): | ||
+ | list_display = (' | ||
+ | search_fields = [' | ||
+ | filter_horizontal = (' | ||
+ | |||
+ | @admin.register(MusicAlbum) | ||
+ | class MusicAlbumAdmin(admin.ModelAdmin): | ||
+ | # form = MusicAlbumAdminForm | ||
+ | list_display = (' | ||
+ | search_fields = [' | ||
+ | filter_horizontal = (' | ||
+ | </ | ||
+ | |||
+ | ===== Zmiana typu pola release_year w modelu Song ===== | ||
+ | Po przeanalizowaniu w przypadku modelu '' | ||
+ | \\ | ||
+ | Poniżej pliki po modyfikacji. | ||
+ | <code python models.py> | ||
+ | from django.db import models | ||
+ | from django.utils import timezone | ||
+ | from .verbose_names import verbose_names | ||
+ | from django.core.validators import MinValueValidator, | ||
+ | |||
+ | # Funkcja walidacyjna dla pola release_year | ||
+ | def validate_release_year(value): | ||
+ | current_year = timezone.now().year | ||
+ | if not str(value).isdigit() or len(str(value)) != 4: | ||
+ | raise ValidationError(" | ||
+ | if value > current_year: | ||
+ | raise ValidationError(" | ||
+ | |||
+ | class Song(models.Model): | ||
+ | song_title = models.CharField(max_length=200, | ||
+ | release_year = models.PositiveIntegerField( | ||
+ | validators=[MinValueValidator(1000), | ||
+ | duration = models.DurationField(null=True, | ||
+ | created_at = models.DateTimeField(default=timezone.now, | ||
+ | modified_at = models.DateTimeField(auto_now=True, | ||
+ | |||
+ | class Meta: | ||
+ | verbose_name = ' | ||
+ | verbose_name_plural = ' | ||
+ | unique_together = (' | ||
+ | |||
+ | def __str__(self): | ||
+ | return f" | ||
+ | |||
+ | class Artist(models.Model): | ||
+ | artist_name = models.CharField(max_length=255, | ||
+ | songs = models.ManyToManyField(Song) | ||
+ | |||
+ | class Meta: | ||
+ | verbose_name = ' | ||
+ | verbose_name_plural = ' | ||
+ | |||
+ | def __str__(self): | ||
+ | return self.artist_name | ||
+ | |||
+ | class MusicAlbum(models.Model): | ||
+ | MEDIUM_TYPE = ( | ||
+ | (' | ||
+ | (' | ||
+ | (' | ||
+ | ) | ||
+ | album_title = models.CharField(max_length=255, | ||
+ | medium_type = models.CharField(max_length=50, | ||
+ | disc_number = models.PositiveIntegerField( | ||
+ | validators=[MinValueValidator(1), | ||
+ | MaxValueValidator(50)], | ||
+ | ) | ||
+ | total_disc = models.PositiveIntegerField( | ||
+ | validators=[MinValueValidator(1), | ||
+ | MaxValueValidator(50)], | ||
+ | ) | ||
+ | songs = models.ManyToManyField(Song) | ||
+ | |||
+ | def __str__(self): | ||
+ | return f" | ||
+ | |||
+ | def clean(self): | ||
+ | if self.disc_number and self.total_disc and self.disc_number > self.total_disc: | ||
+ | raise ValidationError(" | ||
+ | </ | ||
+ | <code python admin.py> | ||
+ | from django.contrib import admin | ||
+ | from .models import Song, Artist, MusicAlbum | ||
+ | from django import forms | ||
+ | |||
+ | class SongAdminForm(forms.ModelForm): | ||
+ | class Meta: | ||
+ | model = Song | ||
+ | fields = [' | ||
+ | |||
+ | def __init__(self, | ||
+ | super().__init__(*args, | ||
+ | |||
+ | # Dodaj placeholder do pola duration | ||
+ | self.fields[' | ||
+ | |||
+ | # Dodaj placeholder do pola rok | ||
+ | self.fields[' | ||
+ | |||
+ | |||
+ | def clean_duration(self): | ||
+ | duration = self.cleaned_data[' | ||
+ | |||
+ | # Sprawdzamy, czy duration ma poprawny format (HH: | ||
+ | if duration.total_seconds() < 0: | ||
+ | raise forms.ValidationError(' | ||
+ | |||
+ | # Sprawdzamy, czy duration nie przekracza 01:59:59 | ||
+ | if duration.total_seconds() > 7199: | ||
+ | raise forms.ValidationError(' | ||
+ | |||
+ | return duration | ||
+ | |||
+ | class ArtistInline(admin.TabularInline): | ||
+ | model = Artist.songs.through | ||
+ | extra = 1 | ||
+ | |||
+ | @admin.register(Song) | ||
+ | class SongAdmin(admin.ModelAdmin): | ||
+ | form = SongAdminForm | ||
+ | list_display = (' | ||
+ | list_filter = (' | ||
+ | search_fields = (' | ||
+ | readonly_fields = [' | ||
+ | inlines = [ArtistInline] | ||
+ | |||
+ | @admin.register(Artist) | ||
+ | class ArtistAdmin(admin.ModelAdmin): | ||
+ | list_display = (' | ||
+ | search_fields = [' | ||
+ | filter_horizontal = (' | ||
+ | |||
+ | @admin.register(MusicAlbum) | ||
+ | class MusicAlbumAdmin(admin.ModelAdmin): | ||
+ | # form = MusicAlbumAdminForm | ||
+ | list_display = (' | ||
+ | search_fields = [' | ||
+ | filter_horizontal = (' | ||
+ | </ | ||
+ | |||
+ | ===== Zmiana organizacji modeli ===== | ||
+ | |||
+ | Do tego momentu utwory były bezpośrednio dodawane do albumu. Skoro album może się składać z kilku nośników (płyt) dodajemy kolejny model ' | ||
+ | |||
+ | ===== Założenia w pliku modeli po modyfikacji ===== | ||
+ | |||
+ | <code python models.py> | ||
+ | from django.db import models | ||
+ | from django.utils import timezone | ||
+ | from .verbose_names import verbose_names | ||
+ | from django.core.validators import MinValueValidator, | ||
+ | |||
+ | # Funkcja walidacyjna dla pola release_year | ||
+ | def validate_release_year(value): | ||
+ | current_year = timezone.now().year | ||
+ | if not str(value).isdigit() or len(str(value)) != 4: | ||
+ | raise ValidationError(" | ||
+ | if value > current_year: | ||
+ | raise ValidationError(" | ||
+ | |||
+ | class Song(models.Model): | ||
+ | song_title = models.CharField(max_length=200, | ||
+ | release_year = models.PositiveIntegerField( | ||
+ | validators=[MinValueValidator(1000), | ||
+ | duration = models.DurationField(null=True, | ||
+ | created_at = models.DateTimeField(default=timezone.now, | ||
+ | modified_at = models.DateTimeField(auto_now=True, | ||
+ | |||
+ | class Meta: | ||
+ | verbose_name = ' | ||
+ | verbose_name_plural = ' | ||
+ | unique_together = (' | ||
+ | |||
+ | def __str__(self): | ||
+ | return f" | ||
+ | |||
+ | class Artist(models.Model): | ||
+ | artist_name = models.CharField(max_length=255, | ||
+ | songs = models.ManyToManyField(Song) | ||
+ | |||
+ | class Meta: | ||
+ | verbose_name = ' | ||
+ | verbose_name_plural = ' | ||
+ | |||
+ | def __str__(self): | ||
+ | return self.artist_name | ||
+ | |||
+ | class MusicAlbum(models.Model): | ||
+ | album_title = models.CharField(max_length=255, | ||
+ | total_disc = models.PositiveIntegerField( | ||
+ | validators=[MinValueValidator(1), | ||
+ | MaxValueValidator(50)], | ||
+ | ) | ||
+ | def __str__(self): | ||
+ | return f" | ||
+ | |||
+ | class StorageMedium(models.Model): | ||
+ | MEDIUM_TYPE = ( | ||
+ | (' | ||
+ | (' | ||
+ | (' | ||
+ | ) | ||
+ | albums_title = models.ForeignKey(' | ||
+ | | ||
+ | disc_title = models.CharField(max_length=255, | ||
+ | medium_type = models.CharField(max_length=50, | ||
+ | disc_number = models.PositiveIntegerField( | ||
+ | validators=[MinValueValidator(1), | ||
+ | MaxValueValidator(50)], | ||
+ | ) | ||
+ | songs = models.ManyToManyField(Song, | ||
+ | |||
+ | class Meta: | ||
+ | unique_together = (' | ||
+ | |||
+ | def clean(self): | ||
+ | super().clean() | ||
+ | |||
+ | if self.disc_number > self.albums_title.total_disc: | ||
+ | raise ValidationError({' | ||
+ | |||
+ | def __str__(self): | ||
+ | return f"W albumie \" | ||
+ | </ | ||
+ | |||
+ | ===== Założenia w pliku admin po modyfikacji ===== | ||
+ | |||
+ | <code python admin.py> | ||
+ | from django.contrib import admin | ||
+ | from .models import Song, Artist, MusicAlbum, StorageMedium | ||
+ | from django import forms | ||
+ | |||
+ | class SongAdminForm(forms.ModelForm): | ||
+ | class Meta: | ||
+ | model = Song | ||
+ | fields = [' | ||
+ | |||
+ | def __init__(self, | ||
+ | super().__init__(*args, | ||
+ | |||
+ | # Dodaj placeholder do pola duration | ||
+ | self.fields[' | ||
+ | |||
+ | # Dodaj placeholder do pola rok | ||
+ | self.fields[' | ||
+ | |||
+ | |||
+ | def clean_duration(self): | ||
+ | duration = self.cleaned_data[' | ||
+ | |||
+ | # Sprawdzamy, czy duration ma poprawny format (HH: | ||
+ | if duration.total_seconds() < 0: | ||
+ | raise forms.ValidationError(' | ||
+ | |||
+ | # Sprawdzamy, czy duration nie przekracza 01:59:59 | ||
+ | if duration.total_seconds() > 7199: | ||
+ | raise forms.ValidationError(' | ||
+ | |||
+ | return duration | ||
+ | |||
+ | class ArtistInline(admin.TabularInline): | ||
+ | model = Artist.songs.through | ||
+ | extra = 1 | ||
+ | |||
+ | @admin.register(Song) | ||
+ | class SongAdmin(admin.ModelAdmin): | ||
+ | form = SongAdminForm | ||
+ | list_display = (' | ||
+ | list_filter = (' | ||
+ | search_fields = (' | ||
+ | readonly_fields = [' | ||
+ | inlines = [ArtistInline] | ||
+ | |||
+ | @admin.register(Artist) | ||
+ | class ArtistAdmin(admin.ModelAdmin): | ||
+ | list_display = (' | ||
+ | search_fields = [' | ||
+ | filter_horizontal = (' | ||
+ | |||
+ | class StorageMediumInline(admin.StackedInline): | ||
+ | model = StorageMedium | ||
+ | extra = 1 | ||
+ | filter_horizontal = (' | ||
+ | |||
+ | @admin.register(MusicAlbum) | ||
+ | class MusicAlbumAdmin(admin.ModelAdmin): | ||
+ | search_fields = [' | ||
+ | inlines = [StorageMediumInline] | ||
+ | |||
+ | @admin.register(StorageMedium) | ||
+ | class StorageMediumAdmin(admin.ModelAdmin): | ||
+ | filter_horizontal = (' | ||
+ | search_fields = [' | ||
+ | list_filter = (' | ||
+ | </ | ||
+ | |||
pl/python/dbaudiocd.1700746697.txt.gz · ostatnio zmienione: 2023/11/23 14:38 przez sindap