From 8b55be1b9c5a6e2764d6c6a3d84d2dd90ac2c42e Mon Sep 17 00:00:00 2001 From: maciejrusek Date: Thu, 12 Mar 2026 23:24:14 +0100 Subject: [PATCH] Added some logic --- backend/apps/authentication/serializers.py | 37 +++++++++++++++++++ backend/apps/authentication/urls.py | 7 +++- backend/apps/authentication/views.py | 8 +++- backend/apps/authors/__init__.py | 0 backend/apps/authors/admin.py | 3 ++ backend/apps/authors/apps.py | 5 +++ backend/apps/authors/migrations/__init__.py | 0 backend/apps/authors/models.py | 6 +++ backend/apps/authors/serializers.py | 0 backend/apps/authors/tests.py | 3 ++ backend/apps/authors/urls.py | 9 +++++ backend/apps/authors/views.py | 20 ++++++++++ backend/apps/books/__init__.py | 0 backend/apps/books/admin.py | 3 ++ backend/apps/books/apps.py | 5 +++ backend/apps/books/migrations/__init__.py | 0 backend/apps/books/models.py | 11 ++++++ backend/apps/books/serializers.py | 25 +++++++++++++ backend/apps/books/tests.py | 3 ++ backend/apps/books/urls.py | 9 +++++ backend/apps/books/views.py | 19 ++++++++++ backend/apps/categories/__init__.py | 0 backend/apps/categories/admin.py | 3 ++ backend/apps/categories/apps.py | 5 +++ .../apps/categories/migrations/__init__.py | 0 backend/apps/categories/models.py | 3 ++ backend/apps/categories/tests.py | 3 ++ backend/apps/categories/views.py | 3 ++ backend/apps/notes/__init__.py | 0 backend/apps/notes/admin.py | 3 ++ backend/apps/notes/apps.py | 5 +++ backend/apps/notes/migrations/__init__.py | 0 backend/apps/notes/models.py | 3 ++ backend/apps/notes/tests.py | 3 ++ backend/apps/notes/views.py | 3 ++ backend/apps/shelf_items/__init__.py | 0 backend/apps/shelf_items/admin.py | 3 ++ backend/apps/shelf_items/apps.py | 5 +++ .../apps/shelf_items/migrations/__init__.py | 0 backend/apps/shelf_items/models.py | 3 ++ backend/apps/shelf_items/tests.py | 3 ++ backend/apps/shelf_items/views.py | 3 ++ backend/apps/shelves/views.py | 6 ++- backend/apps/urls.py | 6 ++- backend/apps/user/apps.py | 6 +++ backend/apps/user/signals.py | 0 backend/config/django/base.py | 2 + backend/requirements.txt | 3 +- 48 files changed, 240 insertions(+), 7 deletions(-) create mode 100644 backend/apps/authentication/serializers.py create mode 100644 backend/apps/authors/__init__.py create mode 100644 backend/apps/authors/admin.py create mode 100644 backend/apps/authors/apps.py create mode 100644 backend/apps/authors/migrations/__init__.py create mode 100644 backend/apps/authors/models.py create mode 100644 backend/apps/authors/serializers.py create mode 100644 backend/apps/authors/tests.py create mode 100644 backend/apps/authors/urls.py create mode 100644 backend/apps/authors/views.py create mode 100644 backend/apps/books/__init__.py create mode 100644 backend/apps/books/admin.py create mode 100644 backend/apps/books/apps.py create mode 100644 backend/apps/books/migrations/__init__.py create mode 100644 backend/apps/books/models.py create mode 100644 backend/apps/books/serializers.py create mode 100644 backend/apps/books/tests.py create mode 100644 backend/apps/books/urls.py create mode 100644 backend/apps/books/views.py create mode 100644 backend/apps/categories/__init__.py create mode 100644 backend/apps/categories/admin.py create mode 100644 backend/apps/categories/apps.py create mode 100644 backend/apps/categories/migrations/__init__.py create mode 100644 backend/apps/categories/models.py create mode 100644 backend/apps/categories/tests.py create mode 100644 backend/apps/categories/views.py create mode 100644 backend/apps/notes/__init__.py create mode 100644 backend/apps/notes/admin.py create mode 100644 backend/apps/notes/apps.py create mode 100644 backend/apps/notes/migrations/__init__.py create mode 100644 backend/apps/notes/models.py create mode 100644 backend/apps/notes/tests.py create mode 100644 backend/apps/notes/views.py create mode 100644 backend/apps/shelf_items/__init__.py create mode 100644 backend/apps/shelf_items/admin.py create mode 100644 backend/apps/shelf_items/apps.py create mode 100644 backend/apps/shelf_items/migrations/__init__.py create mode 100644 backend/apps/shelf_items/models.py create mode 100644 backend/apps/shelf_items/tests.py create mode 100644 backend/apps/shelf_items/views.py create mode 100644 backend/apps/user/signals.py diff --git a/backend/apps/authentication/serializers.py b/backend/apps/authentication/serializers.py new file mode 100644 index 0000000..c8cad44 --- /dev/null +++ b/backend/apps/authentication/serializers.py @@ -0,0 +1,37 @@ +from django.contrib.auth.password_validation import validate_password as django_validate_password +from django.core.exceptions import ValidationError +from rest_framework import serializers +from apps.user.models import User + + +class RegisterSerializer(serializers.ModelSerializer): + + class Meta: + model = User + fields = ["username", "email", "password"] + extra_kwargs = { + "password": {"write_only": True} + } + + def validate_email(self, value): + if User.objects.filter(email=value).exists(): + raise serializers.ValidationError("Email already taken") + return value + + def validate_password(self, value): + try: + django_validate_password(value) + except ValidationError as error: + raise serializers.ValidationError(error.messages) + + return value + + def create(self, validated_data): + user = User.objects.create_user( + validated_data["username"], + validated_data["email"], + validated_data["password"] + ) + + + return user \ No newline at end of file diff --git a/backend/apps/authentication/urls.py b/backend/apps/authentication/urls.py index 532b54c..a911bee 100644 --- a/backend/apps/authentication/urls.py +++ b/backend/apps/authentication/urls.py @@ -5,9 +5,14 @@ from rest_framework_simplejwt.views import ( TokenVerifyView ) +from apps.authentication.views import RegisterView + urlpatterns = [ path('login/', TokenObtainPairView.as_view(), name='token_obtain_pair'), - #path('signup/', ), + path('register', RegisterView.as_view()), + + + path('refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('verify/', TokenVerifyView.as_view(), name='token_verify'), diff --git a/backend/apps/authentication/views.py b/backend/apps/authentication/views.py index 91ea44a..3e145ed 100644 --- a/backend/apps/authentication/views.py +++ b/backend/apps/authentication/views.py @@ -1,3 +1,9 @@ -from django.shortcuts import render +from rest_framework import generics + +from apps.authentication.serializers import RegisterSerializer # Create your views here. +class RegisterView(generics.CreateAPIView): + serializer_class = RegisterSerializer + authentication_classes = [] + permission_classes = [] \ No newline at end of file diff --git a/backend/apps/authors/__init__.py b/backend/apps/authors/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/authors/admin.py b/backend/apps/authors/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/backend/apps/authors/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/backend/apps/authors/apps.py b/backend/apps/authors/apps.py new file mode 100644 index 0000000..ff70d06 --- /dev/null +++ b/backend/apps/authors/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class AuthorsConfig(AppConfig): + name = 'apps.authors' diff --git a/backend/apps/authors/migrations/__init__.py b/backend/apps/authors/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/authors/models.py b/backend/apps/authors/models.py new file mode 100644 index 0000000..f4980e5 --- /dev/null +++ b/backend/apps/authors/models.py @@ -0,0 +1,6 @@ +from django.db import models +from apps.user.models import User + +class Author(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Authors") + name = models.CharField(max_length=255) \ No newline at end of file diff --git a/backend/apps/authors/serializers.py b/backend/apps/authors/serializers.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/authors/tests.py b/backend/apps/authors/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backend/apps/authors/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backend/apps/authors/urls.py b/backend/apps/authors/urls.py new file mode 100644 index 0000000..70042c4 --- /dev/null +++ b/backend/apps/authors/urls.py @@ -0,0 +1,9 @@ +from rest_framework.routers import DefaultRouter + +from apps.authors.views import AuthorsViewSet + +urlpatterns = [] + +router = DefaultRouter() +router.register("", viewset=AuthorsViewSet) +urlpatterns += router.urls \ No newline at end of file diff --git a/backend/apps/authors/views.py b/backend/apps/authors/views.py new file mode 100644 index 0000000..ba890c7 --- /dev/null +++ b/backend/apps/authors/views.py @@ -0,0 +1,20 @@ +from rest_framework import viewsets + +from apps.authors.models import Author +from apps.authors.serializers import AuthorSerializer +from rest_framework import viewsets +from rest_framework.permissions import IsAuthenticated +from rest_framework_simplejwt.authentication import JWTAuthentication + +class AuthorsViewSet(viewsets.ModelViewSet): + queryset = Author.objects.select_related("shelf") + serializer_class = AuthorSerializer + + authentication_classes = [JWTAuthentication] + permission_classes = [IsAuthenticated] + + def get_queryset(self): + return self.queryset.filter( + shelf__user_id=self.request.user.pk + ) + diff --git a/backend/apps/books/__init__.py b/backend/apps/books/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/books/admin.py b/backend/apps/books/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/backend/apps/books/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/backend/apps/books/apps.py b/backend/apps/books/apps.py new file mode 100644 index 0000000..3158566 --- /dev/null +++ b/backend/apps/books/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class BooksConfig(AppConfig): + name = 'apps.books' diff --git a/backend/apps/books/migrations/__init__.py b/backend/apps/books/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/books/models.py b/backend/apps/books/models.py new file mode 100644 index 0000000..19bac53 --- /dev/null +++ b/backend/apps/books/models.py @@ -0,0 +1,11 @@ +from django.db import models + +from apps.shelves.models import Shelf +from apps.authors.models import Author +from apps.user.models import User + +class Book(models.Model): + user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Authors") + authors = models.ManyToManyField(Author, related_name="books") + name = models.CharField(max_length=255) + isbn = models.CharField(max_length=13) \ No newline at end of file diff --git a/backend/apps/books/serializers.py b/backend/apps/books/serializers.py new file mode 100644 index 0000000..c83261b --- /dev/null +++ b/backend/apps/books/serializers.py @@ -0,0 +1,25 @@ +from rest_framework import serializers + +from apps.books.models import Book +from apps.shelves.serializers import ShelfSerializer +from apps.shelves.models import Shelf + +class BookSerializer(serializers.ModelSerializer): + #shelf = ShelfSerializer(read_only=True) + #shelf_id = serializers.PrimaryKeyRelatedField( + #queryset=Shelf.objects.all(), + #source="shelf", + #write_only=True + #) + + + class Meta: + model = Book + fields = [ + "id", + "name", + "isbn", + #"shelf", + #"shelf_id" + ] + read_only_fields = ["id"] \ No newline at end of file diff --git a/backend/apps/books/tests.py b/backend/apps/books/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backend/apps/books/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backend/apps/books/urls.py b/backend/apps/books/urls.py new file mode 100644 index 0000000..41d1a3a --- /dev/null +++ b/backend/apps/books/urls.py @@ -0,0 +1,9 @@ +from rest_framework.routers import DefaultRouter + +from apps.books.views import BooksViewSet + +urlpatterns = [] + +router = DefaultRouter() +router.register("", viewset=BooksViewSet) +urlpatterns += router.urls \ No newline at end of file diff --git a/backend/apps/books/views.py b/backend/apps/books/views.py new file mode 100644 index 0000000..08f78b6 --- /dev/null +++ b/backend/apps/books/views.py @@ -0,0 +1,19 @@ +from rest_framework import viewsets + +from apps.books.models import Book +from apps.books.serializers import BookSerializer +from rest_framework import viewsets +from rest_framework.permissions import IsAuthenticated +from rest_framework_simplejwt.authentication import JWTAuthentication + +class BooksViewSet(viewsets.ModelViewSet): + queryset = Book.objects.prefetch_related("authors") + serializer_class = BookSerializer + + authentication_classes = [JWTAuthentication] + permission_classes = [IsAuthenticated] + + def get_queryset(self): + return self.queryset.filter( + shelf__user_id=self.request.user.pk + ) diff --git a/backend/apps/categories/__init__.py b/backend/apps/categories/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/categories/admin.py b/backend/apps/categories/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/backend/apps/categories/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/backend/apps/categories/apps.py b/backend/apps/categories/apps.py new file mode 100644 index 0000000..0ab5f86 --- /dev/null +++ b/backend/apps/categories/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class CategoriesConfig(AppConfig): + name = 'categories' diff --git a/backend/apps/categories/migrations/__init__.py b/backend/apps/categories/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/categories/models.py b/backend/apps/categories/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/backend/apps/categories/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/backend/apps/categories/tests.py b/backend/apps/categories/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backend/apps/categories/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backend/apps/categories/views.py b/backend/apps/categories/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/backend/apps/categories/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/backend/apps/notes/__init__.py b/backend/apps/notes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/notes/admin.py b/backend/apps/notes/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/backend/apps/notes/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/backend/apps/notes/apps.py b/backend/apps/notes/apps.py new file mode 100644 index 0000000..b6155ac --- /dev/null +++ b/backend/apps/notes/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class NotesConfig(AppConfig): + name = 'notes' diff --git a/backend/apps/notes/migrations/__init__.py b/backend/apps/notes/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/notes/models.py b/backend/apps/notes/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/backend/apps/notes/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/backend/apps/notes/tests.py b/backend/apps/notes/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backend/apps/notes/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backend/apps/notes/views.py b/backend/apps/notes/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/backend/apps/notes/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/backend/apps/shelf_items/__init__.py b/backend/apps/shelf_items/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/shelf_items/admin.py b/backend/apps/shelf_items/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/backend/apps/shelf_items/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/backend/apps/shelf_items/apps.py b/backend/apps/shelf_items/apps.py new file mode 100644 index 0000000..95c030a --- /dev/null +++ b/backend/apps/shelf_items/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class ShelfItemsConfig(AppConfig): + name = 'shelf_items' diff --git a/backend/apps/shelf_items/migrations/__init__.py b/backend/apps/shelf_items/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/apps/shelf_items/models.py b/backend/apps/shelf_items/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/backend/apps/shelf_items/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/backend/apps/shelf_items/tests.py b/backend/apps/shelf_items/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/backend/apps/shelf_items/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/backend/apps/shelf_items/views.py b/backend/apps/shelf_items/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/backend/apps/shelf_items/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here. diff --git a/backend/apps/shelves/views.py b/backend/apps/shelves/views.py index 4efacc5..19f83e3 100644 --- a/backend/apps/shelves/views.py +++ b/backend/apps/shelves/views.py @@ -14,6 +14,8 @@ class ShelvesViewSet(viewsets.ModelViewSet): permission_classes = [IsAuthenticated] def get_queryset(self): - return Shelf.objects.filter(user_id=self.request.user.pk) - + return self.queryset.filter( + user_id=self.request.user.pk + ) + diff --git a/backend/apps/urls.py b/backend/apps/urls.py index 90cce89..b8ab880 100644 --- a/backend/apps/urls.py +++ b/backend/apps/urls.py @@ -2,8 +2,10 @@ from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView from django.urls import include, path urlpatterns = [ - path("auth", include("apps.authentication.urls")), - path("shelves", include("apps.shelves.urls")), + path("auth/", include("apps.authentication.urls")), + path("shelves/", include("apps.shelves.urls")), + path("books/", include("apps.books.urls")), + path("authors/", include("apps.authors.urls")), path('schema/', SpectacularAPIView.as_view(), name='schema'), path('swagger/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'), diff --git a/backend/apps/user/apps.py b/backend/apps/user/apps.py index 850997f..9b6adc4 100644 --- a/backend/apps/user/apps.py +++ b/backend/apps/user/apps.py @@ -3,3 +3,9 @@ from django.apps import AppConfig class UserConfig(AppConfig): name = 'apps.user' + + + def ready(self): + + + return super().ready() \ No newline at end of file diff --git a/backend/apps/user/signals.py b/backend/apps/user/signals.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/config/django/base.py b/backend/config/django/base.py index 557d2a9..8267c17 100644 --- a/backend/config/django/base.py +++ b/backend/config/django/base.py @@ -19,6 +19,8 @@ INSTALLED_APPS = [ "apps.authentication.apps.AuthenticationConfig", "apps.user.apps.UserConfig", "apps.shelves.apps.ShelvesConfig", + "apps.books.apps.BooksConfig", + "apps.authors.apps.AuthorsConfig", "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", diff --git a/backend/requirements.txt b/backend/requirements.txt index 0a70b1f..0f80f4b 100644 --- a/backend/requirements.txt +++ b/backend/requirements.txt @@ -4,4 +4,5 @@ djangorestframework==3.16.1 django-filter==25.2 djangorestframework-simplejwt==5.5.1 drf-spectacular==0.29.0 -pillow==12.1.1 \ No newline at end of file +pillow==12.1.1 +celery==5.6.2 \ No newline at end of file