Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
08e9541177
|
|
@ -3,6 +3,7 @@ ITRadio/ITRadioBackend/db.sqlite3
|
|||
*.py[cod]
|
||||
node_modules/
|
||||
dist/
|
||||
conf.dev/
|
||||
/conf
|
||||
var
|
||||
server/proj/media
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
from rest_framework.schemas import AutoSchema
|
||||
import coreapi
|
||||
import coreschema
|
||||
|
||||
|
||||
class UpdateUserSchema(AutoSchema):
|
||||
def get_serializer_fields(self, path, method):
|
||||
return [
|
||||
coreapi.Field(
|
||||
name='email',
|
||||
location='form',
|
||||
required=False,
|
||||
schema=coreschema.String(description='Email пользователя')
|
||||
),
|
||||
coreapi.Field(
|
||||
name='old_password',
|
||||
location='form',
|
||||
required=False,
|
||||
schema=coreschema.String(description='Старый пароль')
|
||||
),
|
||||
coreapi.Field(
|
||||
name='password',
|
||||
location='form',
|
||||
required=False,
|
||||
schema=coreschema.String(description='Новый пароль')
|
||||
),
|
||||
]
|
||||
|
|
@ -11,11 +11,7 @@ class MyUserSerializer(ModelSerializer):
|
|||
|
||||
class Meta:
|
||||
model = MyUser
|
||||
fields = ('id', 'email', 'password',
|
||||
'first_name', 'last_name',
|
||||
'phone', 'date_joined',
|
||||
'number',
|
||||
)
|
||||
fields = ('id', 'email', 'password', 'date_joined')
|
||||
extra_kwargs = {
|
||||
'password': {'write_only': True},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,12 +5,21 @@ from rest_framework_simplejwt.views import TokenObtainPairView
|
|||
from rest_framework.decorators import action
|
||||
from rest_framework import status
|
||||
from django.core.mail import send_mail
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from django.contrib.auth.hashers import make_password, check_password
|
||||
from conf import settings
|
||||
from account.serializers import MyUserSerializer, MyTokenObtainPairSerializer
|
||||
from account.models import MyUser
|
||||
from .schemas import UpdateUserSchema
|
||||
from conf.settings.base import MIN_LEN_PASSWORD
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.validators import validate_email
|
||||
|
||||
PermissionClass = IsAuthenticated if not settings.DEBUG else AllowAny
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class MyTokenObtainPairView(TokenObtainPairView):
|
||||
permission_classes = [AllowAny]
|
||||
serializer_class = MyTokenObtainPairSerializer
|
||||
|
|
@ -53,17 +62,45 @@ class MyUserViewSet(ViewSet):
|
|||
token_serializer.is_valid(raise_exception=True)
|
||||
return Response(token_serializer.validated_data, status=status.HTTP_201_CREATED)
|
||||
|
||||
@action(detail=False, methods=['post'])
|
||||
@action(detail=False, methods=['post'], schema=UpdateUserSchema())
|
||||
def update_user(self, request):
|
||||
if 'email' in request.data:
|
||||
del request.data['email']
|
||||
if 'password' in request.data:
|
||||
request.data['password'] = make_password(request.data['password'])
|
||||
serializer = MyUserSerializer(request.user, data=request.data, partial=True)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
password = request.user.password
|
||||
|
||||
if check_password(request.data['old_password'], password):
|
||||
try:
|
||||
validate_email(request.data['password'])
|
||||
except ValidationError as e:
|
||||
pass
|
||||
else:
|
||||
return Response(
|
||||
{'detail': 'Почта не может являться паролем', 'error': {'email': 'Почта не может являться паролем'}},
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
if len(request.data['password']) < MIN_LEN_PASSWORD:
|
||||
return Response(
|
||||
{'detail': 'Минимальная длина - 8 символов', 'error': {'email': 'Минимальная длина - 8 символов'}},
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
if check_password(request.data['password'], password):
|
||||
return Response(
|
||||
{'detail': 'Пароли одинаковые', 'error': {'email': 'Пароли одинаковые'}},
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
if 'email' in request.data:
|
||||
del request.data['email']
|
||||
if 'password' in request.data:
|
||||
request.data['password'] = make_password(request.data['password'])
|
||||
serializer = MyUserSerializer(request.user, data=request.data, partial=True)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
else:
|
||||
return Response(
|
||||
{'detail': 'Неверный старый пароль', 'error': {'email': 'Неверный старый пароль'}},
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
return Response(serializer.data)
|
||||
|
||||
@action(detail=False, methods=['post'])
|
||||
def password_reset_user(self, request):
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-21 17:43
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='NowPlayingSong',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('title', models.CharField(max_length=255)),
|
||||
('artist', models.CharField(max_length=255)),
|
||||
('album', models.CharField(blank=True, max_length=255, null=True)),
|
||||
('genre', models.CharField(blank=True, max_length=100, null=True)),
|
||||
('art_url', models.URLField(blank=True, null=True)),
|
||||
('duration', models.IntegerField()),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-21 18:13
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('api', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='nowplayingsong',
|
||||
name='duration',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-21 18:51
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('api', '0002_remove_nowplayingsong_duration'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name='nowplayingsong',
|
||||
old_name='art_url',
|
||||
new_name='art',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-24 14:17
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('api', '0003_rename_art_url_nowplayingsong_art'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(
|
||||
name='NowPlayingSong',
|
||||
),
|
||||
]
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
from django.contrib import admin
|
||||
from .models import Song, FavoriteSong
|
||||
from .models import Song, FavoriteSong, PlayList
|
||||
|
||||
@admin.register(Song)
|
||||
class SongAdmin(admin.ModelAdmin):
|
||||
|
|
@ -9,3 +9,7 @@ class SongAdmin(admin.ModelAdmin):
|
|||
@admin.register(FavoriteSong)
|
||||
class FavoriteSongAdmin(admin.ModelAdmin):
|
||||
list_display = ('id', 'song', 'user')
|
||||
|
||||
@admin.register(PlayList)
|
||||
class PlayListAdmin(admin.ModelAdmin):
|
||||
list_display = ('id', 'name', 'user', 'art')
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ class Song(models.Model):
|
|||
|
||||
class Meta:
|
||||
verbose_name = 'Треки'
|
||||
unique_together = ('azura_id', )
|
||||
verbose_name_plural = 'Треки'
|
||||
|
||||
|
||||
|
|
@ -36,3 +37,15 @@ class FavoriteSong(models.Model):
|
|||
verbose_name = 'Избранные Треки'
|
||||
unique_together = ('song', 'user')
|
||||
verbose_name_plural = 'Избранные Треки'
|
||||
|
||||
|
||||
class PlayList(models.Model):
|
||||
name = models.CharField('Название плейлиста', max_length=50, blank=True, null=True)
|
||||
song = models.ManyToManyField(Song, blank=True, null=True)
|
||||
user = models.ForeignKey(MyUser, verbose_name='Пользователь', on_delete=models.CASCADE)
|
||||
art = models.ImageField('Изображение плейлиста', blank=True, null=True, upload_to="playlist_images/")
|
||||
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'Плейлисты'
|
||||
verbose_name_plural = 'Плейлисты'
|
||||
|
|
@ -53,3 +53,26 @@ class DeleteSongSchema(AutoSchema):
|
|||
schema=coreschema.String(description='ID трека с Азуры')
|
||||
),
|
||||
]
|
||||
|
||||
class PlayListSchema(AutoSchema):
|
||||
def get_serializer_fields(self, path, method):
|
||||
return [
|
||||
coreapi.Field(
|
||||
name='name',
|
||||
location='form',
|
||||
required=False,
|
||||
schema=coreschema.String(description='Название плейлиста')
|
||||
),
|
||||
coreapi.Field(
|
||||
name='playlist_id',
|
||||
location='form',
|
||||
required=False,
|
||||
schema=coreschema.Integer(description='ID плейлиста')
|
||||
),
|
||||
coreapi.Field(
|
||||
name='azura_id',
|
||||
location='form',
|
||||
required=False,
|
||||
schema=coreschema.String(description='ID трека с азуры')
|
||||
),
|
||||
]
|
||||
|
|
@ -1,11 +1,24 @@
|
|||
from rest_framework import serializers
|
||||
from .models import Song, FavoriteSong
|
||||
from .models import Song, FavoriteSong, PlayList
|
||||
|
||||
class SongSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Song
|
||||
fields = ('id', 'unique_id', 'azura_id', 'title', 'artist', 'album', 'genre', 'art')
|
||||
|
||||
class PlayListSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = PlayList
|
||||
fields = ('id', 'name', 'song', 'user')
|
||||
|
||||
def to_representation(self, instance):
|
||||
rep = super().to_representation(instance)
|
||||
rep["song"] = SongSerializer(
|
||||
instance.song.all(), many=True).data
|
||||
return rep
|
||||
|
||||
|
||||
|
||||
class FavoriteSongSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
|
|
|
|||
|
|
@ -5,13 +5,97 @@ from rest_framework.decorators import action
|
|||
from rest_framework import status
|
||||
from django.core.exceptions import ObjectDoesNotExist, MultipleObjectsReturned
|
||||
from django.shortcuts import get_object_or_404, get_list_or_404
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.permissions import IsAuthenticated, AllowAny
|
||||
import requests
|
||||
from django.http import HttpResponse
|
||||
|
||||
from .schemas import SongSchema, DeleteSongSchema
|
||||
from .models import Song, FavoriteSong
|
||||
from .serializers import SongSerializer, FavoriteSongSerializer
|
||||
from .schemas import SongSchema, DeleteSongSchema, PlayListSchema
|
||||
from .models import Song, FavoriteSong, PlayList
|
||||
from .serializers import SongSerializer, FavoriteSongSerializer, PlayListSerializer
|
||||
|
||||
class PlayListViewSet(GenericViewSet):
|
||||
queryset = PlayList
|
||||
serializer_class = PlayListSerializer
|
||||
permission_classes = (IsAuthenticated,)
|
||||
def list(self, request):
|
||||
queryset = self.get_queryset().objects.filter(user=request.user)
|
||||
serializer = self.get_serializer(queryset, many=True)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
|
||||
def retrieve(self, request, pk):
|
||||
try:
|
||||
queryset = self.get_queryset().objects.get(pk=pk, user=request.user)
|
||||
serializer = self.get_serializer(queryset)
|
||||
return Response(serializer.data, status=status.HTTP_200_OK)
|
||||
except ObjectDoesNotExist:
|
||||
return Response(
|
||||
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@action(detail=False, methods=['post'], schema=PlayListSchema())
|
||||
def create_playlist(self, request):
|
||||
|
||||
if request.data.get('name', False):
|
||||
try:
|
||||
instance = PlayList.objects.get(pk=request.data['playlist_id'], user=request.user.pk)
|
||||
data = request.data
|
||||
data.update(user=request.user.pk)
|
||||
serializer = self.get_serializer(data=request.data, instance=instance)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
except ObjectDoesNotExist:
|
||||
return Response(
|
||||
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
else:
|
||||
playlist_pk = self.get_queryset().objects.filter(user=request.user.pk)
|
||||
number_playlist = len(playlist_pk) + 1
|
||||
name = f"Плейлист № {number_playlist}"
|
||||
data = request.data
|
||||
data.update(user=request.user.pk, name=name)
|
||||
serializer = self.get_serializer(data=request.data)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
|
||||
@action(detail=False, methods=['post'], schema=PlayListSchema())
|
||||
def delete_playlist(self, request):
|
||||
try:
|
||||
item = PlayList.objects.get(user=request.user, pk=request.data.get('playlist_id'))
|
||||
item.delete()
|
||||
return Response(status=status.HTTP_202_ACCEPTED)
|
||||
except ObjectDoesNotExist:
|
||||
return Response(
|
||||
{'detail': 'Объекта не существует', 'error': {'PlayList': 'Объекта не существует'}},
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@action(detail=False, methods=['post'], schema=PlayListSchema())
|
||||
def add_to_playlist(self, request):
|
||||
try:
|
||||
song = list(Song.objects.filter(azura_id=request.data.get('azura_id')).values_list('pk', flat=True))
|
||||
except ObjectDoesNotExist:
|
||||
return Response(
|
||||
{'detail': 'Песни не существует', 'error': {'Song': 'Песни не существует'}},
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
try:
|
||||
instance = PlayList.objects.get(pk=request.data.get('playlist_id'))
|
||||
except ObjectDoesNotExist:
|
||||
return Response(
|
||||
{'detail': 'Плейлиста не существует', 'error': {'PlayList': 'Плейлиста не существует'}},
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
songs = list(instance.song.all().values_list('pk', flat=True))+song
|
||||
data = {
|
||||
'playlist_id': request.data.get('playlist_id'),
|
||||
'song': songs
|
||||
}
|
||||
serializer = PlayListSerializer(data=data, partial=True, instance=instance)
|
||||
serializer.is_valid(raise_exception=True)
|
||||
serializer.save()
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
class SongViewSet(GenericViewSet):
|
||||
queryset = Song.objects.all()
|
||||
|
|
@ -108,6 +192,24 @@ class SongViewSet(GenericViewSet):
|
|||
except ObjectDoesNotExist:
|
||||
return Response({"error": 'Объекта не существует'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@action(detail=False, methods=['get'])
|
||||
def get_all_song(self, request):
|
||||
file_url = "http://82.97.242.49:10084/api/station/1/files"
|
||||
API_KEY = "49226d3488aac3f5:18d88659c6c1c5e131a0ce0a94d55235"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {API_KEY}"
|
||||
}
|
||||
response = requests.get(file_url, headers=headers)
|
||||
data = []
|
||||
for i in response.json():
|
||||
i['azura_id'] = i.pop('song_id')
|
||||
data.append(i)
|
||||
|
||||
|
||||
|
||||
return Response(data, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
|
@ -0,0 +1 @@
|
|||
from .local import *
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
from .development import *
|
||||
from .local import *
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -132,38 +132,7 @@ LOGGING = {
|
|||
'style': '{',
|
||||
},
|
||||
},
|
||||
'handlers': {
|
||||
'update_history': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.handlers.RotatingFileHandler',
|
||||
'filename': LOG_ROOT / 'update_history.log',
|
||||
'formatter': 'extended',
|
||||
'maxBytes': ROTATE_LOG_SIZE,
|
||||
'backupCount': ROTATE_LOG_COUNT,
|
||||
},
|
||||
'upload_media': {
|
||||
'level': 'DEBUG',
|
||||
'class': 'logging.handlers.RotatingFileHandler',
|
||||
'filename': LOG_ROOT / 'upload_media.log',
|
||||
'formatter': 'extended',
|
||||
'maxBytes': ROTATE_LOG_SIZE,
|
||||
'backupCount': ROTATE_LOG_COUNT,
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'update_history': {
|
||||
'handlers': ['update_history', ],
|
||||
'level': 'INFO',
|
||||
'propagate': False,
|
||||
},
|
||||
'upload_media': {
|
||||
'handlers': ['upload_media', ],
|
||||
'level': 'INFO',
|
||||
'propagate': False,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DEFAULT_PERMISSION_CLASSES': [
|
||||
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
|
||||
|
|
@ -191,3 +160,4 @@ CORS_ALLOW_CREDENTIALS = True
|
|||
CORS_ALLOWED_ORIGINS = [
|
||||
'http://localhost:5173',
|
||||
]
|
||||
MIN_LEN_PASSWORD = 8
|
||||
|
|
@ -6,7 +6,7 @@ ALLOWED_HOSTS = ['*']
|
|||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
|
||||
""" DATABASES = {
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||
'NAME': 'it_radio',
|
||||
|
|
@ -15,12 +15,6 @@ ALLOWED_HOSTS = ['*']
|
|||
'HOST': 'localhost',
|
||||
'PORT': '5433',
|
||||
},
|
||||
} """
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
|
||||
REST_FRAMEWORK['DEFAULT_PERMISSION_CLASSES'] = ('rest_framework.permissions.AllowAny',)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
import sys
|
||||
from .base import *
|
||||
|
||||
DEBUG = True
|
||||
ALLOWED_HOSTS = ['*']
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.sqlite3',
|
||||
'NAME': BASE_DIR / 'db.sqlite3',
|
||||
}
|
||||
}
|
||||
REST_FRAMEWORK['DEFAULT_PERMISSION_CLASSES'] = ('rest_framework.permissions.AllowAny',)
|
||||
|
||||
if len(sys.argv) >= 2 and not sys.argv[0].endswith('manage.py'):
|
||||
from conf.sentry import sentry_start, SENTRY_CONFIG
|
||||
|
||||
SENTRY_CONFIG['environment'] = 'local'
|
||||
sentry_start(SENTRY_CONFIG)
|
||||
|
|
@ -2,19 +2,20 @@ import sys
|
|||
from .base import *
|
||||
|
||||
DEBUG = False
|
||||
ALLOWED_HOSTS = ['*']
|
||||
ALLOWED_HOSTS = ['82.97.242.49']
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
|
||||
""" DATABASES = {
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'ENGINE': 'django.db.backends.postgresql_psycopg2',
|
||||
'NAME': 'ldirect',
|
||||
'USER': 'flexites',
|
||||
'PASSWORD': 'flexites',
|
||||
'NAME': 'itradio',
|
||||
'USER': 'postgres',
|
||||
'PASSWORD': '55667788Vxod',
|
||||
'HOST': 'localhost',
|
||||
'PORT': '5432',
|
||||
},
|
||||
} """
|
||||
}
|
||||
|
||||
if len(sys.argv) >= 2 and sys.argv[1] != 'runserver':
|
||||
from conf.sentry import sentry_start, SENTRY_CONFIG
|
||||
|
|
|
|||
|
|
@ -12,12 +12,13 @@ from userProfile.views import TeamViewSet
|
|||
from django.conf import settings
|
||||
from rubricks.views import RubricViewSet
|
||||
from api.views import FetchAndServeFile
|
||||
from audio.views import SongViewSet
|
||||
from audio.views import SongViewSet, PlayListViewSet
|
||||
|
||||
|
||||
router = routers.DefaultRouter()
|
||||
router.register(r'teams', TeamViewSet, basename='teams')
|
||||
router.register(r'rubriks', RubricViewSet, basename='rubriks')
|
||||
router.register(r'playlists', PlayListViewSet, basename='playlists')
|
||||
router.register(r'song', SongViewSet, basename='song')
|
||||
router.register(r'fetchandservefile', FetchAndServeFile, basename='fetchandservefile')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-16 15:16
|
||||
# Generated by Django 5.0.6 on 2024-06-19 12:09
|
||||
|
||||
import django.utils.timezone
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
|
@ -12,13 +13,11 @@ class Migration(migrations.Migration):
|
|||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='News',
|
||||
name='HistoryRadio',
|
||||
fields=[
|
||||
('id', models.BigAutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('description', models.TextField()),
|
||||
('date', models.DateTimeField()),
|
||||
('author', models.CharField(max_length=255)),
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('description', models.CharField(max_length=50, verbose_name='Описание события кратко')),
|
||||
('date', models.DateField(default=django.utils.timezone.now, null=True, verbose_name='Дата события')),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-16 15:47
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('news', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='news',
|
||||
name='author',
|
||||
field=models.CharField(blank=True, max_length=255),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='news',
|
||||
name='date',
|
||||
field=models.DateTimeField(blank=True),
|
||||
),
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-16 15:16
|
||||
# Generated by Django 5.0.6 on 2024-06-19 12:09
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
|
@ -14,10 +14,15 @@ class Migration(migrations.Migration):
|
|||
migrations.CreateModel(
|
||||
name='Rubric',
|
||||
fields=[
|
||||
('id', models.BigAutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('description', models.TextField()),
|
||||
('time', models.DateTimeField()),
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255, verbose_name='Название рубрики')),
|
||||
('title', models.TextField(default='Null', max_length=1000, null=True, verbose_name='Заголовок рубрики')),
|
||||
('description', models.TextField(max_length=1000, verbose_name='Описание рубрики')),
|
||||
('img', models.ImageField(blank=True, null=True, upload_to='images/', verbose_name='Изображение рубрики')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Рубрики',
|
||||
'verbose_name_plural': 'Рубрики',
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-16 16:10
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rubricks', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='rubric',
|
||||
name='time',
|
||||
field=models.DateTimeField(blank=True),
|
||||
),
|
||||
]
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
# Generated by Django 5.0.4 on 2024-05-06 19:19
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('rubricks', '0002_alter_rubric_time'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='rubric',
|
||||
name='time',
|
||||
),
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,13 +1,9 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from rest_framework.authtoken.admin import TokenAdmin
|
||||
from .models import Team
|
||||
|
||||
|
||||
|
||||
TokenAdmin.raw_id_fields = ['user']
|
||||
|
||||
|
||||
@admin.register(Team)
|
||||
class TeamAdmin(admin.ModelAdmin):
|
||||
list_display = ('id', 'name', 'last_name', 'position', 'img_person')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
# Generated by Django 5.0.4 on 2024-04-25 14:58
|
||||
# Generated by Django 5.0.6 on 2024-06-19 12:09
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
|
@ -10,16 +8,21 @@ class Migration(migrations.Migration):
|
|||
initial = True
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Profile',
|
||||
name='Team',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('likedSongs', models.JSONField(default=list)),
|
||||
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
('name', models.CharField(max_length=50, verbose_name='Имя участника')),
|
||||
('last_name', models.CharField(max_length=50, verbose_name='Фамилия участника')),
|
||||
('position', models.CharField(max_length=50, verbose_name='Должность участинка')),
|
||||
('img_person', models.ImageField(blank=True, null=True, upload_to='team_images/', verbose_name='Изображение участника')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Команда',
|
||||
'verbose_name_plural': 'Команда',
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
# Generated by Django 5.0.4 on 2024-05-06 19:19
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('userProfile', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='profile',
|
||||
name='likedSongs',
|
||||
field=models.JSONField(blank=True, null=True),
|
||||
),
|
||||
]
|
||||
Binary file not shown.
Binary file not shown.
|
|
@ -2,34 +2,6 @@ from django.contrib.auth.models import User
|
|||
from django.db import models
|
||||
from django.db.models import JSONField
|
||||
|
||||
""" class Profile(models.Model):
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
|
||||
likedSongs = JSONField(blank=True, null=True)
|
||||
"""
|
||||
|
||||
# likedSongs = models.ManyToManyField(Song)
|
||||
# likedSongs = models.TextField()
|
||||
# podcasts = models.ManyToManyField(Podcast)
|
||||
# playlists = models.ManyToManyField(Playlist)
|
||||
|
||||
|
||||
# #JWT
|
||||
# from django.contrib.auth.models import User
|
||||
# from rest_framework.authtoken.models import Token
|
||||
|
||||
# for user in User.objects.all():
|
||||
# Token.objects.get_or_create(user=user)
|
||||
|
||||
# from django.conf import settings
|
||||
# from django.db.models.signals import post_save
|
||||
# from django.dispatch import receiver
|
||||
|
||||
# @receiver(post_save, sender=settings.AUTH_USER_MODEL)
|
||||
# def create_auth_token(sender, instance=None, created=False, **kwargs):
|
||||
# if created:
|
||||
# Token.objects.create(user=instance)
|
||||
|
||||
class Team(models.Model):
|
||||
name = models.CharField('Имя участника', max_length=50)
|
||||
last_name = models.CharField('Фамилия участника', max_length=50)
|
||||
|
|
|
|||
|
|
@ -2,25 +2,6 @@ from rest_framework import serializers, views, status
|
|||
from rest_framework.response import Response
|
||||
from .models import Team
|
||||
|
||||
""" class ProfileSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Profile
|
||||
fields = ['user', 'likedSongs']
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
new_song = validated_data.get('likedSongs')
|
||||
if new_song:
|
||||
current_songs = instance.likedSongs or []
|
||||
# Check if the song ID already exists in the current songs
|
||||
if not any(song['id'] == new_song['id'] for song in current_songs):
|
||||
current_songs.append(new_song)
|
||||
instance.likedSongs = current_songs
|
||||
instance.save()
|
||||
return instance
|
||||
def create(self, validated_data):
|
||||
validated_data['likedSongs'] = []
|
||||
return Profile.objects.create(**validated_data) """
|
||||
|
||||
class TeamSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Team
|
||||
|
|
|
|||
|
|
@ -8,61 +8,9 @@ from rest_framework.decorators import api_view, permission_classes, action
|
|||
from django.contrib.auth.models import User
|
||||
from rest_framework_simplejwt.authentication import JWTAuthentication
|
||||
from rest_framework_simplejwt.exceptions import InvalidToken, AuthenticationFailed
|
||||
|
||||
""" from .models import Profile, Team
|
||||
from .serializers import ProfileSerializer, TeamSerializer """
|
||||
|
||||
from .models import Team
|
||||
from .serializers import TeamSerializer
|
||||
|
||||
""" class ProfileViewSet(viewsets.ViewSet):
|
||||
queryset = Profile.objects.all()
|
||||
def list(self, request):
|
||||
queryset = Profile.objects.all()
|
||||
serializer = ProfileSerializer(queryset, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
|
||||
@action(detail=False, methods=['post'])
|
||||
def AddSong(self, request):
|
||||
if request.method == 'POST':
|
||||
user = request.user.pk
|
||||
new_song = request.data.get('new_song') # new_song should be a dict
|
||||
profile = get_object_or_404(Profile, user=user)
|
||||
serializer = ProfileSerializer(profile, data={'likedSongs': new_song}, partial=True)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
return Response(serializer.data, status=status.HTTP_201_CREATED)
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@action(detail=False, methods=['post'])
|
||||
def DeleteSong(self, request):
|
||||
user = request.user.pk
|
||||
song_id = request.data.get('id') # Assuming each song has a unique 'id' field
|
||||
if not song_id:
|
||||
return Response({'error': 'Song ID is required'}, status=status.HTTP_400_BAD_REQUEST)
|
||||
profile = get_object_or_404(Profile, user=user)
|
||||
if profile.likedSongs:
|
||||
# Filter out the song with the given ID
|
||||
updated_songs = [song for song in profile.likedSongs if song.get('id') != song_id]
|
||||
profile.likedSongs = updated_songs
|
||||
profile.save()
|
||||
return Response({'message': 'Song deleted'}, status=status.HTTP_204_NO_CONTENT)
|
||||
else:
|
||||
return Response({'error': 'No songs to delete'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
@action(
|
||||
detail=False,
|
||||
methods=['get'],
|
||||
url_path='getlikedsongs/',
|
||||
url_name='liked_songs',
|
||||
)
|
||||
def GetLikedSongs(request):
|
||||
if request.method == 'GET':
|
||||
user = request.user.pk
|
||||
profile = get_object_or_404(Profile, user=user)
|
||||
serializer = ProfileSerializer(profile)
|
||||
return Response(serializer.data['likedSongs'], status=status.HTTP_200_OK) """
|
||||
|
||||
class TeamViewSet(ViewSet):
|
||||
def list(self, request):
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
asgiref==3.8.1
backports.zoneinfo==0.2.1
certifi==2024.2.2
charset-normalizer==3.3.2
coreapi==2.3.3
coreschema==0.0.4
Django==4.1
django-coreapi==2.3.0
django-cors-headers==4.3.1
django-filter==24.2
djangorestframework==3.15.1
djangorestframework-simplejwt==5.3.1
idna==3.7
importlib_metadata==7.1.0
itypes==1.2.0
Jinja2==3.1.4
Markdown==3.6
MarkupSafe==2.1.5
pillow==10.3.0
psycopg2==2.9.9
PyJWT==2.8.0
pytz==2024.1
PyYAML==6.0.1
requests==2.32.2
sqlparse==0.5.0
typing_extensions==4.12.0
tzdata==2024.1
uritemplate==4.1.1
urllib3==1.26.15
zipp==3.19.0
|
||||
asgiref==3.8.1
backports.zoneinfo==0.2.1
certifi==2024.2.2
charset-normalizer==3.3.2
coreapi==2.3.3
coreschema==0.0.4
django-coreapi==2.3.0
django-cors-headers==4.3.1
django-filter==24.2
djangorestframework==3.15.1
djangorestframework-simplejwt==5.3.1
idna==3.7
importlib_metadata==7.1.0
itypes==1.2.0
Jinja2==3.1.4
Markdown==3.6
MarkupSafe==2.1.5
pillow==10.3.0
PyJWT==2.8.0
pytz==2024.1
PyYAML==6.0.1
requests==2.32.2
sqlparse==0.5.0
typing_extensions==4.12.0
tzdata==2024.1
uritemplate==4.1.1
zipp==3.19.0
|
||||
Loading…
Reference in New Issue