backend merge
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
from django.contrib import admin
|
||||
|
||||
# Register your models here.
|
||||
@@ -0,0 +1,6 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AccountConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'account'
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.db import models
|
||||
|
||||
# Create your models here.
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
@@ -16,7 +16,8 @@ urlpatterns = [
|
||||
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||
path('admin/', admin.site.urls),
|
||||
path('schema/', SpectacularAPIView.as_view(), name='schema'),
|
||||
path('comment/<int:pk>', views.CommentView.as_view(), name='comment-list'),
|
||||
# path('comment/<int:pk>', views.CommentView.as_view(), name='comment-list'),
|
||||
path('products/', include('product.urls')),
|
||||
path('', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
|
||||
]
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
from django.contrib import admin
|
||||
from import_export.admin import ImportExportActionModelAdmin
|
||||
from unfold.admin import ModelAdmin
|
||||
from .models import *
|
||||
|
||||
|
||||
@admin.register(Dare)
|
||||
class Dare(ModelAdmin):
|
||||
list_display = ['lang1', 'is_for_adults']
|
||||
list_filter = ['is_for_adults']
|
||||
|
||||
|
||||
@admin.register(Truth)
|
||||
class Truth(ModelAdmin):
|
||||
list_display = ['lang1', 'is_for_adults']
|
||||
list_filter = ['is_for_adults']
|
||||
|
||||
|
||||
@admin.register(Would_you_rather)
|
||||
class Would_you_rather(ModelAdmin):
|
||||
list_display = ['lang1', 'is_for_adults']
|
||||
list_filter = ['is_for_adults']
|
||||
|
||||
|
||||
@admin.register(challenge)
|
||||
class Challenge(ModelAdmin):
|
||||
list_display = ['type']
|
||||
|
||||
@admin.register(abjad)
|
||||
class abjad(ModelAdmin):
|
||||
list_display = ['word', 'difficulty_type', 'answer']
|
||||
list_filter = ['difficulty_type']
|
||||
|
||||
|
||||
|
||||
@admin.register(MusicModel)
|
||||
class MusicAdmin(ModelAdmin):
|
||||
list_display = ['name', 'message_id', 'singer', 'category', 'trand']
|
||||
|
||||
@admin.register(MovieModel)
|
||||
class MovieAdmin(ModelAdmin):
|
||||
list_display = ['name', 'message_id', 'category', 'receommended']
|
||||
|
||||
@admin.register(MovieCategory)
|
||||
class MovieCategoryAdmin(ModelAdmin):
|
||||
pass
|
||||
|
||||
@admin.register(MusicCategory)
|
||||
class MusicCategoryAdmin(ModelAdmin):
|
||||
pass
|
||||
@@ -0,0 +1,7 @@
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class EntertainmentConfig(AppConfig):
|
||||
default_auto_field = 'django.db.models.BigAutoField'
|
||||
name = 'entertainment'
|
||||
verbose_name = 'بخش سرگرمی ها'
|
||||
@@ -0,0 +1,142 @@
|
||||
from django.db import models
|
||||
|
||||
|
||||
class BaseModel(models.Model):
|
||||
lang1 = models.CharField(max_length=200, verbose_name='فارسی')
|
||||
is_for_adults = models.BooleanField(verbose_name='+18 سوال')
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
def __str__(self):
|
||||
return self.lang1
|
||||
|
||||
async def get(self, *attrs):
|
||||
if len(attrs) == 1:
|
||||
return getattr(self, attrs[0], None)
|
||||
else:
|
||||
return tuple(getattr(self, attr, None) for attr in attrs)
|
||||
|
||||
|
||||
class Dare(BaseModel):
|
||||
class Meta:
|
||||
verbose_name = 'شجاعت'
|
||||
verbose_name_plural = 'شجاعت ها'
|
||||
|
||||
|
||||
class Truth(BaseModel):
|
||||
class Meta:
|
||||
verbose_name = 'حقیقت'
|
||||
verbose_name_plural = "حقیقت ها"
|
||||
|
||||
|
||||
class Would_you_rather(BaseModel):
|
||||
class Meta:
|
||||
verbose_name = 'ترجیح میدی'
|
||||
verbose_name_plural = "ترجیح میدی ها"
|
||||
|
||||
|
||||
class challenge(models.Model):
|
||||
challenge_type = (
|
||||
('map', 'نقشه ی گنج'),
|
||||
('prize', 'جوایز')
|
||||
)
|
||||
type = models.CharField(max_length=30, choices=challenge_type, verbose_name='نوع چالش', primary_key=True)
|
||||
image = models.ImageField(upload_to='media/', verbose_name='عکس')
|
||||
link = models.URLField(verbose_name='لینک')
|
||||
text = models.TextField(verbose_name='متن توضیحات')
|
||||
button_text = models.CharField(max_length=40, verbose_name='متن دکمه')
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.type} - {self.text[0:50]}'
|
||||
class Meta:
|
||||
verbose_name = 'چالش'
|
||||
verbose_name_plural = 'چالش ها'
|
||||
|
||||
class abjad(models.Model):
|
||||
word = models.TextField(verbose_name='صورت ی سوال')
|
||||
difficulty = (
|
||||
('hard', 'سخت'),
|
||||
('normal', 'متوسط'),
|
||||
('easy', 'اسون')
|
||||
)
|
||||
image = models.ImageField(upload_to='media/', verbose_name='عکس بازی افتابه', blank=True, null=True)
|
||||
difficulty_type = models.CharField(max_length=13, choices=difficulty, verbose_name='سختی')
|
||||
answer = models.CharField(max_length=30, verbose_name='جواب')
|
||||
option2 = models.CharField(max_length=30, verbose_name='گزینه ی اشتباه', null=True, blank=True)
|
||||
option3 = models.CharField(max_length=30, verbose_name='گزینه ی اشتباه', null=True, blank=True)
|
||||
option4 = models.CharField(max_length=30, verbose_name='گزینه ی اشتباه', null=True, blank=True)
|
||||
def __str__(self):
|
||||
return f'{self.word}'
|
||||
class Meta:
|
||||
verbose_name = 'سوال ابجد'
|
||||
verbose_name_plural = 'سوالات ابجد'
|
||||
async def get(self, *attrs):
|
||||
if len(attrs) == 1:
|
||||
return getattr(self, attrs[0], None)
|
||||
else:
|
||||
return tuple(getattr(self, attr, None) for attr in attrs)
|
||||
|
||||
GAME_DATA = {
|
||||
Dare: {
|
||||
'button': 'dare',
|
||||
'game_name': 'شجاعت'
|
||||
},
|
||||
Truth: {
|
||||
'button': 'truth',
|
||||
'game_name': 'حقیقت'
|
||||
},
|
||||
Would_you_rather: {
|
||||
'button': 'wyr',
|
||||
'game_name': 'ترجیح میدی'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
from django.db import models
|
||||
|
||||
|
||||
class MusicCategory(models.Model):
|
||||
name = models.CharField(max_length=40, verbose_name='نام دسته بندی')
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'دسته بندی موزیک'
|
||||
verbose_name_plural = 'دسته بندی موزیک ها'
|
||||
|
||||
class MovieCategory(models.Model):
|
||||
name = models.CharField(max_length=40, verbose_name='نام دسته بندی')
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Meta:
|
||||
verbose_name = 'دسته بندی قیلم'
|
||||
verbose_name_plural = 'دسته بندی فیلم ها'
|
||||
|
||||
|
||||
class UploadParent(models.Model):
|
||||
name = models.CharField(max_length=300, verbose_name='نام')
|
||||
message_id = models.CharField(max_length=40, verbose_name='ای دی پیام تلگرام')
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class MusicModel(UploadParent):
|
||||
lyric = models.CharField(verbose_name='متن اهنگ', max_length=4000, blank=True, null=True)
|
||||
singer = models.CharField(max_length=300, verbose_name='خواننده', blank=True, null=True)
|
||||
category = models.ForeignKey(MusicCategory, on_delete=models.CASCADE, verbose_name='دسته بندی', blank=True, null=True)
|
||||
trand = models.BooleanField(default=False, verbose_name='ترند')
|
||||
class Meta:
|
||||
verbose_name = 'مدل اهنگ'
|
||||
verbose_name_plural = 'مدل اهنگ ها'
|
||||
|
||||
|
||||
class MovieModel(UploadParent):
|
||||
description = models.CharField(max_length=4000,verbose_name='توضیحات فیلم', blank=True, null=True)
|
||||
category = models.ForeignKey(MovieCategory, on_delete=models.CASCADE, verbose_name='دسته بندی', blank=True, null=True)
|
||||
receommended = models.BooleanField(default=False, verbose_name='پیشنهادی')
|
||||
class Meta:
|
||||
verbose_name = 'مدل فیلم'
|
||||
verbose_name_plural = 'مدل فیلم ها'
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
@@ -0,0 +1,3 @@
|
||||
from django.shortcuts import render
|
||||
|
||||
# Create your views here.
|
||||
@@ -0,0 +1,31 @@
|
||||
# Generated by Django 5.1.2 on 2024-12-13 07:51
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('product', '0004_rename_product_productmodel'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CategoryModel',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=50, verbose_name='نام دسته\u200cبندی')),
|
||||
('slug', models.SlugField(help_text='اسم دسته را برای مسیر به انگلیسی و بدون فاصله وارد کنید', unique=True)),
|
||||
('icon', models.CharField(blank=True, max_length=100, null=True, verbose_name='آیکون دسته\u200cبندی')),
|
||||
('meta_title', models.CharField(blank=True, help_text='عنوان متا برای SEO', max_length=60, null=True, verbose_name='عنوان متا')),
|
||||
('meta_description', models.TextField(blank=True, help_text='توضیحات متا برای SEO', max_length=160, null=True, verbose_name='توضیحات متا')),
|
||||
('parent', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='product.categorymodel', verbose_name='دسته\u200cبندی والد')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'دسته\u200cبندی',
|
||||
'verbose_name_plural': 'دسته\u200cبندی\u200cها',
|
||||
'ordering': ['parent__id', 'id'],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -1,6 +1,58 @@
|
||||
from django.db import models
|
||||
from django.utils.text import slugify
|
||||
from django.contrib.auth.models import User
|
||||
from django.urls import reverse
|
||||
|
||||
class CategoryModel(models.Model):
|
||||
name = models.CharField(max_length=50, verbose_name='نام دستهبندی')
|
||||
slug = models.SlugField(
|
||||
max_length=50,
|
||||
unique=True,
|
||||
help_text="اسم دسته را برای مسیر به انگلیسی و بدون فاصله وارد کنید"
|
||||
)
|
||||
parent = models.ForeignKey(
|
||||
'self',
|
||||
on_delete=models.CASCADE,
|
||||
related_name='children',
|
||||
null=True,
|
||||
blank=True,
|
||||
verbose_name='دستهبندی والد'
|
||||
)
|
||||
icon = models.CharField(max_length=100, verbose_name='آیکون دستهبندی', blank=True, null=True)
|
||||
meta_title = models.CharField(
|
||||
max_length=60,
|
||||
verbose_name="عنوان متا",
|
||||
help_text="عنوان متا برای SEO",
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
meta_description = models.TextField(
|
||||
max_length=160,
|
||||
verbose_name="توضیحات متا",
|
||||
help_text="توضیحات متا برای SEO",
|
||||
blank=True,
|
||||
null=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "دستهبندی"
|
||||
verbose_name_plural = "دستهبندیها"
|
||||
ordering = ['parent__id', 'id'] # Optional: to order by hierarchy
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('category_detail', kwargs={'slug': self.slug})
|
||||
|
||||
def get_breadcrumb(self):
|
||||
breadcrumb = []
|
||||
category = self
|
||||
while category:
|
||||
breadcrumb.append(category)
|
||||
category = category.parent
|
||||
return breadcrumb[::-1]
|
||||
|
||||
class ProductModel(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
description = models.TextField()
|
||||
|
||||
@@ -1,9 +1,28 @@
|
||||
from .models import *
|
||||
from rest_framework import serializers
|
||||
|
||||
class ProductSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = ProductModel
|
||||
fields = "__all__"
|
||||
|
||||
|
||||
class CommentSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = CommentModel
|
||||
fields = "__all__"
|
||||
read_only_fields = ('show', 'product')
|
||||
read_only_fields = ('show', 'product')
|
||||
|
||||
|
||||
class CategorySerializer(serializers.ModelSerializer):
|
||||
children = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = CategoryModel
|
||||
fields = ['id', 'name', 'slug', 'icon', 'meta_title', 'meta_description', 'parent', 'children']
|
||||
|
||||
def get_children(self, obj):
|
||||
children = obj.children.all()
|
||||
if children.exists():
|
||||
return CategorySerializer(children, many=True).data
|
||||
return []
|
||||
@@ -0,0 +1,10 @@
|
||||
from django.urls import path
|
||||
from .views import AllCategories, ProductView, AllProductsView, CommentView
|
||||
|
||||
urlpatterns = [
|
||||
path('', AllProductsView.as_view(), name='category-products'),
|
||||
path('categories', AllCategories.as_view(), name='all-categories'),
|
||||
path('<int:pk>', ProductView.as_view(), name='product-detail'),
|
||||
path('<int:pk>/comments', CommentView.as_view(), name='product-comments'),
|
||||
path('comments/<int:pk>', CommentView.as_view(), name='comment-delete'),
|
||||
]
|
||||
+119
-2
@@ -7,6 +7,123 @@ from rest_framework.response import Response
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework.permissions import IsAuthenticatedOrReadOnly
|
||||
from utils.pagination import StructurePagination
|
||||
from drf_spectacular.utils import extend_schema, OpenApiParameter
|
||||
from drf_spectacular.types import OpenApiTypes
|
||||
|
||||
|
||||
class AllCategories(APIView):
|
||||
serializer_class = CategorySerializer
|
||||
def get(self, request):
|
||||
categories = CategoryModel.objects.all()
|
||||
categories_ser = self.serializer_class(instance=categories, many=True)
|
||||
return Response({"categories": categories_ser.data}, status=status.HTTP_200_OK)
|
||||
|
||||
class ProductView(APIView):
|
||||
serializer_class = ProductModel
|
||||
def get(self, request, pk):
|
||||
product = get_object_or_404(ProductModel, id=pk)
|
||||
product_ser = self.serializer_class(instance=product, many=False)
|
||||
return Response({"product": product_ser.data}, status=status.HTTP_200_OK)
|
||||
|
||||
class AllProductsView(APIView):
|
||||
serializer_class = ProductSerializer
|
||||
pagination_class = StructurePagination
|
||||
|
||||
@extend_schema(
|
||||
parameters=[
|
||||
OpenApiParameter(
|
||||
name="search",
|
||||
description="Search by product name or description.",
|
||||
required=False,
|
||||
type=OpenApiTypes.STR,
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="category",
|
||||
description="Filter by category ID.",
|
||||
required=False,
|
||||
type=OpenApiTypes.INT,
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="price_gte",
|
||||
description="Filter products with price greater than or equal to this value.",
|
||||
required=False,
|
||||
type=OpenApiTypes.FLOAT,
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="price_lte",
|
||||
description="Filter products with price less than or equal to this value.",
|
||||
required=False,
|
||||
type=OpenApiTypes.FLOAT,
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="sort",
|
||||
description=(
|
||||
"Sort results by one of the following fields:\n"
|
||||
"`name`, `-name`, `price`, `-price`, `discount`, `-discount`."
|
||||
"\nPrefix with `-` for descending order."
|
||||
),
|
||||
required=False,
|
||||
type=OpenApiTypes.STR,
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="limit",
|
||||
description="Number of results to return per page (pagination).",
|
||||
required=False,
|
||||
type=OpenApiTypes.INT,
|
||||
),
|
||||
OpenApiParameter(
|
||||
name="offset",
|
||||
description="The starting position of the results (pagination).",
|
||||
required=False,
|
||||
type=OpenApiTypes.INT,
|
||||
),
|
||||
],
|
||||
description=(
|
||||
"Retrieve products with optional filters and sorting. "
|
||||
"Provide a category ID to filter products in that category and its subcategories."
|
||||
),
|
||||
responses={
|
||||
200: ProductSerializer(many=True),
|
||||
404: OpenApiTypes.OBJECT,
|
||||
},
|
||||
)
|
||||
def get(self, request, pk=None):
|
||||
try:
|
||||
if pk:
|
||||
category = Category.objects.get(pk=pk)
|
||||
products = ProductModel.objects.filter(category__in=category.get_descendants(include_self=True))
|
||||
else:
|
||||
products = ProductModel.objects.all()
|
||||
|
||||
search_query = request.query_params.get('search', None)
|
||||
if search_query:
|
||||
products = products.filter(Q(name__icontains=search_query) | Q(description__icontains=search_query))
|
||||
|
||||
category_filter = request.query_params.get('category', None)
|
||||
if category_filter:
|
||||
products = products.filter(category__id=category_filter)
|
||||
|
||||
price_gte = request.query_params.get('price_gte', None)
|
||||
price_lte = request.query_params.get('price_lte', None)
|
||||
if price_gte:
|
||||
products = products.filter(price__gte=price_gte)
|
||||
if price_lte:
|
||||
products = products.filter(price__lte=price_lte)
|
||||
|
||||
sort_by = request.query_params.get('sort', None)
|
||||
if sort_by in ['name', '-name', 'price', '-price', 'discount', '-discount']:
|
||||
products = products.order_by(sort_by)
|
||||
else:
|
||||
products = products.order_by('name')
|
||||
|
||||
paginator = self.pagination_class()
|
||||
paginated_products = paginator.paginate_queryset(products, request)
|
||||
serializer = self.serializer_class(paginated_products, many=True)
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
except Category.DoesNotExist:
|
||||
return Response({"detail": "Category not found."}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
|
||||
class CommentView(APIView):
|
||||
@@ -22,10 +139,10 @@ class CommentView(APIView):
|
||||
comment_ser = CommentSerializer(data=request.data)
|
||||
product = get_object_or_404(ProductModel, id=pk)
|
||||
if comment_ser.is_valid():
|
||||
comment_ser.save(product=product)
|
||||
#TODO comment_ser.save(product=product, user=request.user)
|
||||
comment_ser.save(product=product, user=request.user)
|
||||
return Response(comment_ser.data, status=status.HTTP_201_CREATED)
|
||||
return Response(comment_ser.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, pk):
|
||||
comment = get_object_or_404(CommentModel, pk=pk)
|
||||
if comment.user == request.user:
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
from django.contrib import admin
|
||||
from unfold.admin import ModelAdmin
|
||||
from .models import NotifModel
|
||||
from import_export.admin import ImportExportModelAdmin
|
||||
from unfold.contrib.import_export.forms import ExportForm, ImportForm, SelectableFieldsExportForm
|
||||
|
||||
@admin.register(NotifModel)
|
||||
class NotifModelAdmin(ModelAdmin, ImportExportModelAdmin):
|
||||
import_form_class = ImportForm
|
||||
export_form_class = ExportForm
|
||||
compressed_fields = True
|
||||
warn_unsaved_form = True
|
||||
|
||||
list_display = ('subject', 'priority', 'send_time', 'send_by', 'send_to_all')
|
||||
search_fields = ('subject', 'description', 'send_by__email', 'send_to_branch__name')
|
||||
list_filter = ('priority', 'send_time', 'send_to_all')
|
||||
ordering = ('-send_time',)
|
||||
filter_horizontal = ('send_to_branch', 'read_by')
|
||||
@@ -0,0 +1,14 @@
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
class GetNotifSerializer(serializers.ModelSerializer):
|
||||
send_by = UserSerializer()
|
||||
is_seen = serializers.SerializerMethodField()
|
||||
read_by = UserSerializer(many=True)
|
||||
class Meta:
|
||||
model = NotifModel
|
||||
fields = ('id', 'subject', 'priority', 'description', 'send_time', 'is_seen', 'send_by', 'read_by')
|
||||
read_only_fields = ("read_by", "send_by")
|
||||
def get_is_seen(self, obj):
|
||||
user = self.context['user']
|
||||
return user in obj.read_by.all()
|
||||
@@ -0,0 +1,37 @@
|
||||
from django.core.paginator import Paginator
|
||||
from rest_framework.views import APIView
|
||||
from .models import *
|
||||
from .serializers import *
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from django.db.models import Q
|
||||
from django.shortcuts import get_object_or_404
|
||||
from rest_framework.permissions import IsAuthenticatedOrReadOnly
|
||||
|
||||
|
||||
class CommentView(APIView):
|
||||
serializer_class = CommentSerializer
|
||||
permission_classes = [IsAuthenticatedOrReadOnly]
|
||||
def get(self, request, pk):
|
||||
product = get_object_or_404(ProductModel, id=pk)
|
||||
comments = product.comments.filter(show=True)
|
||||
comments_ser = self.serializer_class(instance=comments, many=True)
|
||||
return Response({'comments': comments_ser.data}, status=status.HTTP_200_OK)
|
||||
|
||||
def post(self, request, pk):
|
||||
comment_ser = CommentSerializer(data=request.data)
|
||||
product = get_object_or_404(ProductModel, id=pk)
|
||||
if comment_ser.is_valid():
|
||||
comment_ser.save(product=product, user=request.user)
|
||||
return Response(comment_ser.data, status=status.HTTP_201_CREATED)
|
||||
return Response(comment_ser.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
def delete(self, request, pk):
|
||||
comment = get_object_or_404(CommentModel, pk=pk)
|
||||
if comment.user == request.user:
|
||||
comment.delete()
|
||||
return Response(status=status.HTTP_204_NO_CONTENT)
|
||||
else:
|
||||
return Response({"detail": "شما اجازه ی پاک کردن این کامنت را ندارید"}, status=status.HTTP_403_FORBIDDEN)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user