Added some logic

This commit is contained in:
maciejrusek
2026-03-18 19:14:26 +01:00
parent fdcd0653a6
commit 5722f0b7ea
13 changed files with 211 additions and 44 deletions

View File

@@ -2,4 +2,4 @@ from django.apps import AppConfig
class ShelfItemsConfig(AppConfig):
name = 'shelf_items'
name = 'apps.shelf_items'

View File

@@ -1,3 +1,19 @@
from django.db.models import Q, F
from django.db import models
# Create your models here.
from apps.books.models import Book
from apps.shelves.models import Shelf
class ShelfItem(models.Model):
book = models.ForeignKey(Book, on_delete=models.CASCADE, related_name="shelf_items")
shelf = models.ForeignKey(Shelf, on_delete=models.CASCADE, related_name="book_items")
quantity = models.PositiveIntegerField(default=0)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["book", "shelf"],
name="unique_book_per_shelf"
),
]

View File

@@ -0,0 +1,77 @@
from rest_framework import serializers
from apps.shelf_items.models import ShelfItem
from apps.books.models import Book
from apps.shelves.models import Shelf
from apps.shelves.serializers import ShelfSerializer
from apps.books.serializers import BookSerializer
class ShelfItemSerializer(serializers.ModelSerializer):
shelf = ShelfSerializer(read_only=True)
shelf_id = serializers.PrimaryKeyRelatedField(
queryset=Shelf.objects.all(),
source="shelf",
write_only=True
)
book = BookSerializer(read_only=True)
book_id = serializers.PrimaryKeyRelatedField(
queryset=Book.objects.all(),
source="book",
write_only=True
)
class Meta:
model = ShelfItem
fields = [
"id",
"shelf",
"shelf_id",
"book",
"book_id",
"quantity"
]
read_only_fields = ["id"]
def __init__(self, instance=None, data=..., **kwargs):
super().__init__(instance, data, **kwargs)
request = self.context.get("request")
if request and request.user:
self.fields["shelf_id"].queryset = Shelf.objects.filter(
user=request.user
)
self.fields["book_id"].queryset = Book.objects.filter(
user=request.user
)
def validate(self, attrs):
attrs = super().validate(attrs)
book = attrs.get("book")
shelf = attrs.get("shelf")
if book and shelf:
qs = ShelfItem.objects.filter(
book=book,
shelf=shelf
)
if self.instance:
qs = qs.exclude(pk=self.instance.pk)
if qs.exists():
raise serializers.ValidationError(
"This Book already exists in shelf!"
)
if book.user_id != shelf.user_id:
raise serializers.ValidationError(
"Book and Shelf must be from the same user!"
)
return attrs

View File

@@ -0,0 +1,9 @@
from rest_framework.routers import DefaultRouter
from apps.shelf_items.views import ShelfItemsViewSet
urlpatterns = []
router = DefaultRouter()
router.register("", viewset=ShelfItemsViewSet)
urlpatterns += router.urls

View File

@@ -1,3 +1,20 @@
from django.shortcuts import render
from rest_framework import viewsets
# Create your views here.
from apps.shelf_items.models import ShelfItem
from apps.shelf_items.serializers import ShelfItemSerializer
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
class ShelfItemsViewSet(viewsets.ModelViewSet):
queryset = ShelfItem.objects.all()
serializer_class = ShelfItemSerializer
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
def get_queryset(self):
return ShelfItem.objects.filter(
shelf__user_id=self.request.user.pk,
).select_related("book", "shelf").prefetch_related("book__authors")