add: add like model, api, admin
This commit is contained in:
2
core/apps/accounts/admin/__init__.py
Normal file
2
core/apps/accounts/admin/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from .user import *
|
||||||
|
from .like import *
|
||||||
8
core/apps/accounts/admin/like.py
Normal file
8
core/apps/accounts/admin/like.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
from core.apps.accounts.models import Like
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Like)
|
||||||
|
class LikeAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ['id', 'user', 'product']
|
||||||
9
core/apps/accounts/admin/user.py
Normal file
9
core/apps/accounts/admin/user.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
from django.contrib.auth.admin import UserAdmin as DjangoUserAdmin
|
||||||
|
|
||||||
|
from core.apps.accounts.models import User
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(User)
|
||||||
|
class UserAdmin(DjangoUserAdmin):
|
||||||
|
pass
|
||||||
@@ -4,3 +4,6 @@ from django.apps import AppConfig
|
|||||||
class AccountsConfig(AppConfig):
|
class AccountsConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
name = 'core.apps.accounts'
|
name = 'core.apps.accounts'
|
||||||
|
|
||||||
|
def ready(self):
|
||||||
|
from . import admin
|
||||||
31
core/apps/accounts/migrations/0003_like.py
Normal file
31
core/apps/accounts/migrations/0003_like.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Generated by Django 5.2 on 2025-08-28 17:23
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
import uuid
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('accounts', '0002_alter_user_created_at'),
|
||||||
|
('products', '0002_category_name_ru_category_name_uz_and_more'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Like',
|
||||||
|
fields=[
|
||||||
|
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('product', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='likes', to='products.product')),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='likes', to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'verbose_name': 'likelar',
|
||||||
|
'verbose_name_plural': 'likelar',
|
||||||
|
'unique_together': {('user', 'product')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@@ -1 +1,2 @@
|
|||||||
from .user import *
|
from .user import *
|
||||||
|
from .like import *
|
||||||
15
core/apps/accounts/models/like.py
Normal file
15
core/apps/accounts/models/like.py
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
from core.apps.shared.models import BaseModel
|
||||||
|
from core.apps.accounts.models import User
|
||||||
|
from core.apps.products.models import Product
|
||||||
|
|
||||||
|
|
||||||
|
class Like(BaseModel):
|
||||||
|
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='likes')
|
||||||
|
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='likes')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = 'likelar'
|
||||||
|
verbose_name_plural = 'likelar'
|
||||||
|
unique_together = ['user', 'product']
|
||||||
@@ -1,8 +1,11 @@
|
|||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
|
||||||
from rest_framework_simplejwt.views import TokenObtainPairView
|
from rest_framework_simplejwt.views import TokenObtainPairView
|
||||||
|
from core.apps.accounts.views import like as like_views
|
||||||
|
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('login/', TokenObtainPairView.as_view()),
|
path('login/', TokenObtainPairView.as_view()),
|
||||||
|
path('<uuid:product_id>/like/', like_views.LikeApiView.as_view()),
|
||||||
|
path('liked_products/', like_views.LikeProductListApiView.as_view()),
|
||||||
]
|
]
|
||||||
34
core/apps/accounts/views/like.py
Normal file
34
core/apps/accounts/views/like.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
|
from rest_framework import views, permissions, generics
|
||||||
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
from core.apps.accounts.models import Like
|
||||||
|
from core.apps.products.models import Product
|
||||||
|
from core.apps.products.serializers.product import ProductListSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class LikeApiView(views.APIView):
|
||||||
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
|
||||||
|
def get(self, request, product_id):
|
||||||
|
product = get_object_or_404(Product, id=product_id)
|
||||||
|
like, created = Like.objects.get_or_create(product=product, user=request.user)
|
||||||
|
if created:
|
||||||
|
return Response({'success': True, 'message': "Liked"}, status=200)
|
||||||
|
like.delete()
|
||||||
|
return Response({'success': False, 'message': "Unliked"}, status=200)
|
||||||
|
|
||||||
|
|
||||||
|
class LikeProductListApiView(generics.GenericAPIView):
|
||||||
|
serializer_class = ProductListSerializer
|
||||||
|
permission_classes = [permissions.IsAuthenticated]
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
products = Product.objects.filter(likes__user=request.user)
|
||||||
|
page = self.paginate_queryset(products)
|
||||||
|
if page is not None:
|
||||||
|
serializer = self.serializer_class(page, many=True, context={'user': request.user})
|
||||||
|
return self.get_paginated_response(serializer.data)
|
||||||
|
serializer = self.serializer_class(products, many=True, context={'user': request.user})
|
||||||
|
return Response(serializer.data, status=200)
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from core.apps.products.models import Product
|
from core.apps.products.models import Product
|
||||||
|
from core.apps.accounts.models import Like
|
||||||
|
|
||||||
|
|
||||||
class ProductListSerializer(serializers.ModelSerializer):
|
class ProductListSerializer(serializers.ModelSerializer):
|
||||||
|
liked = serializers.SerializerMethodField(method_name='get_liked')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Product
|
model = Product
|
||||||
fields = [
|
fields = [
|
||||||
'id', 'name', 'image', 'price', 'description',
|
'id', 'name', 'image', 'price', 'description', 'liked'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def get_liked(self, obj):
|
||||||
|
return Like.objects.filter(user=self.context.get('user'), product=obj).exists()
|
||||||
@@ -4,11 +4,11 @@ from rest_framework import generics
|
|||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from core.apps.products.models import Product, Category
|
from core.apps.products.models import Product, Category
|
||||||
from core.apps.products.serializers import category as serializers
|
from core.apps.products.serializers import product as serializers
|
||||||
|
|
||||||
|
|
||||||
class ProductListApiView(generics.GenericAPIView):
|
class ProductListApiView(generics.GenericAPIView):
|
||||||
serializer_class = serializers.CategoryListSerializer
|
serializer_class = serializers.ProductListSerializer
|
||||||
queryset = Product.objects.all()
|
queryset = Product.objects.all()
|
||||||
permission_classes = []
|
permission_classes = []
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ class ProductListApiView(generics.GenericAPIView):
|
|||||||
products = Product.objects.filter(category=category)
|
products = Product.objects.filter(category=category)
|
||||||
page = self.paginate_queryset(products)
|
page = self.paginate_queryset(products)
|
||||||
if page is not None:
|
if page is not None:
|
||||||
serializer = self.serializer_class(page, many=True)
|
serializer = self.serializer_class(page, many=True, context={'user': request.user})
|
||||||
return self.get_paginated_response(serializer.data)
|
return self.get_paginated_response(serializer.data)
|
||||||
serializer = self.serializer_class(products, many=True)
|
serializer = self.serializer_class(products, many=True, context={'user': request.user})
|
||||||
return Response(serializer.data, status=200)
|
return Response(serializer.data, status=200)
|
||||||
|
|||||||
Reference in New Issue
Block a user