added bo endpoints for product notes
This commit is contained in:
parent
0fe7c50e5b
commit
9975f3f3b5
|
|
@ -99,6 +99,18 @@ class UserBaseSerializer(serializers.ModelSerializer):
|
||||||
read_only_fields = fields
|
read_only_fields = fields
|
||||||
|
|
||||||
|
|
||||||
|
class UserShortSerializer(UserSerializer):
|
||||||
|
"""Compact serializer for model User."""
|
||||||
|
|
||||||
|
class Meta(UserSerializer.Meta):
|
||||||
|
"""Meta class."""
|
||||||
|
fields = [
|
||||||
|
'id',
|
||||||
|
'fullname',
|
||||||
|
'email',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class ChangePasswordSerializer(serializers.ModelSerializer):
|
class ChangePasswordSerializer(serializers.ModelSerializer):
|
||||||
"""Serializer for model User."""
|
"""Serializer for model User."""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,13 +64,18 @@ class CompanyInline(admin.TabularInline):
|
||||||
extra = 0
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
|
class EstablishmentNote(admin.TabularInline):
|
||||||
|
model = models.EstablishmentNote
|
||||||
|
extra = 0
|
||||||
|
|
||||||
|
|
||||||
@admin.register(models.Establishment)
|
@admin.register(models.Establishment)
|
||||||
class EstablishmentAdmin(BaseModelAdminMixin, admin.ModelAdmin):
|
class EstablishmentAdmin(BaseModelAdminMixin, admin.ModelAdmin):
|
||||||
"""Establishment admin."""
|
"""Establishment admin."""
|
||||||
list_display = ['id', '__str__', 'image_tag', ]
|
list_display = ['id', '__str__', 'image_tag', ]
|
||||||
search_fields = ['id', 'name', 'index_name', 'slug']
|
search_fields = ['id', 'name', 'index_name', 'slug']
|
||||||
list_filter = ['public_mark', 'toque_number']
|
list_filter = ['public_mark', 'toque_number']
|
||||||
inlines = [GalleryImageInline, CompanyInline]
|
inlines = [GalleryImageInline, CompanyInline, EstablishmentNote]
|
||||||
|
|
||||||
# inlines = [
|
# inlines = [
|
||||||
# AwardInline, ContactPhoneInline, ContactEmailInline,
|
# AwardInline, ContactPhoneInline, ContactEmailInline,
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,15 @@ from django.contrib.contenttypes import fields as generic
|
||||||
from django.contrib.gis.db.models.functions import Distance
|
from django.contrib.gis.db.models.functions import Distance
|
||||||
from django.contrib.gis.geos import Point
|
from django.contrib.gis.geos import Point
|
||||||
from django.contrib.gis.measure import Distance as DistanceMeasure
|
from django.contrib.gis.measure import Distance as DistanceMeasure
|
||||||
|
from django.contrib.postgres.fields import ArrayField
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.core.validators import MinValueValidator, MaxValueValidator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q
|
from django.db.models import When, Case, F, ExpressionWrapper, Subquery, Q
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from phonenumber_field.modelfields import PhoneNumberField
|
from phonenumber_field.modelfields import PhoneNumberField
|
||||||
from timezone_field import TimeZoneField
|
from timezone_field import TimeZoneField
|
||||||
from django.contrib.postgres.fields import ArrayField
|
|
||||||
from django.core.validators import MinValueValidator, MaxValueValidator
|
|
||||||
|
|
||||||
from collection.models import Collection
|
from collection.models import Collection
|
||||||
from location.models import Address
|
from location.models import Address
|
||||||
|
|
|
||||||
|
|
@ -231,6 +231,12 @@ class Product(GalleryModelMixin, TranslatedFieldsMixin, BaseAttributes, HasTagsM
|
||||||
"""Override str dunder method."""
|
"""Override str dunder method."""
|
||||||
return f'{self.name}'
|
return f'{self.name}'
|
||||||
|
|
||||||
|
def delete(self, using=None, keep_parents=False):
|
||||||
|
"""Overridden delete method"""
|
||||||
|
# Delete all related notes
|
||||||
|
self.notes.all().delete()
|
||||||
|
return super().delete(using, keep_parents)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def product_type_translated_name(self):
|
def product_type_translated_name(self):
|
||||||
"""Get translated name of product type."""
|
"""Get translated name of product type."""
|
||||||
|
|
@ -431,7 +437,7 @@ class ProductNote(ProjectBaseMixin):
|
||||||
old_id = models.PositiveIntegerField(null=True, blank=True)
|
old_id = models.PositiveIntegerField(null=True, blank=True)
|
||||||
text = models.TextField(verbose_name=_('text'))
|
text = models.TextField(verbose_name=_('text'))
|
||||||
product = models.ForeignKey(Product, on_delete=models.PROTECT,
|
product = models.ForeignKey(Product, on_delete=models.PROTECT,
|
||||||
related_name='product_notes',
|
related_name='notes',
|
||||||
verbose_name=_('product'))
|
verbose_name=_('product'))
|
||||||
user = models.ForeignKey('account.User', on_delete=models.PROTECT,
|
user = models.ForeignKey('account.User', on_delete=models.PROTECT,
|
||||||
null=True,
|
null=True,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ from product import models
|
||||||
from product.serializers import ProductDetailSerializer, ProductTypeBaseSerializer, \
|
from product.serializers import ProductDetailSerializer, ProductTypeBaseSerializer, \
|
||||||
ProductSubTypeBaseSerializer
|
ProductSubTypeBaseSerializer
|
||||||
from tag.models import TagCategory
|
from tag.models import TagCategory
|
||||||
|
from account.serializers.common import UserShortSerializer
|
||||||
|
|
||||||
|
|
||||||
class ProductBackOfficeGallerySerializer(serializers.ModelSerializer):
|
class ProductBackOfficeGallerySerializer(serializers.ModelSerializer):
|
||||||
|
|
@ -127,3 +128,55 @@ class ProductSubTypeBackOfficeDetailSerializer(ProductSubTypeBaseSerializer):
|
||||||
'name',
|
'name',
|
||||||
'index_name',
|
'index_name',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ProductNoteBaseSerializer(serializers.ModelSerializer):
|
||||||
|
"""Serializer for model ProductNote."""
|
||||||
|
|
||||||
|
user_detail = UserShortSerializer(read_only=True, source='user')
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
"""Meta class."""
|
||||||
|
model = models.ProductNote
|
||||||
|
fields = [
|
||||||
|
'id',
|
||||||
|
'created',
|
||||||
|
'modified',
|
||||||
|
'text',
|
||||||
|
'user',
|
||||||
|
'user_detail',
|
||||||
|
'product',
|
||||||
|
]
|
||||||
|
extra_kwargs = {
|
||||||
|
'created': {'read_only': True},
|
||||||
|
'modified': {'read_only': True},
|
||||||
|
'product': {'required': False, 'write_only': True},
|
||||||
|
'user': {'required': False, 'write_only': True},
|
||||||
|
}
|
||||||
|
|
||||||
|
@property
|
||||||
|
def serializer_view(self):
|
||||||
|
"""Return view instance."""
|
||||||
|
return self.context.get('view')
|
||||||
|
|
||||||
|
|
||||||
|
class ProductNoteListCreateSerializer(ProductNoteBaseSerializer):
|
||||||
|
"""Serializer for List|Create action for model ProductNote."""
|
||||||
|
|
||||||
|
def create(self, validated_data):
|
||||||
|
"""Overridden create method."""
|
||||||
|
validated_data['user'] = self.user
|
||||||
|
validated_data['product'] = self.product
|
||||||
|
return super().create(validated_data)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def user(self):
|
||||||
|
"""Return user instance from view."""
|
||||||
|
if self.serializer_view:
|
||||||
|
return self.serializer_view.request.user
|
||||||
|
|
||||||
|
@property
|
||||||
|
def product(self):
|
||||||
|
"""Return product instance from view."""
|
||||||
|
if self.serializer_view:
|
||||||
|
return self.serializer_view.get_object()
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ from product import views
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.ProductListCreateBackOfficeView.as_view(), name='list-create'),
|
path('', views.ProductListCreateBackOfficeView.as_view(), name='list-create'),
|
||||||
path('<int:pk>/', views.ProductDetailBackOfficeView.as_view(), name='rud'),
|
path('<int:pk>/', views.ProductDetailBackOfficeView.as_view(), name='rud'),
|
||||||
|
path('<int:pk>/notes/', views.ProductNoteListCreateView.as_view(), name='note-list-create'),
|
||||||
|
path('<int:pk>/notes/<int:note_pk>/', views.ProductNoteRUDView.as_view(), name='note-rud'),
|
||||||
path('<int:pk>/gallery/', views.ProductBackOfficeGalleryListView.as_view(),
|
path('<int:pk>/gallery/', views.ProductBackOfficeGalleryListView.as_view(),
|
||||||
name='gallery-list'),
|
name='gallery-list'),
|
||||||
path('<int:pk>/gallery/<int:image_id>/', views.ProductBackOfficeGalleryCreateDestroyView.as_view(),
|
path('<int:pk>/gallery/<int:image_id>/', views.ProductBackOfficeGalleryCreateDestroyView.as_view(),
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ from utils.views import CreateDestroyGalleryViewMixin
|
||||||
class ProductBackOfficeMixinView(ProductBaseView):
|
class ProductBackOfficeMixinView(ProductBaseView):
|
||||||
"""Product back-office mixin view."""
|
"""Product back-office mixin view."""
|
||||||
|
|
||||||
permission_classes = (permissions.IsAuthenticated,)
|
permission_classes = (permissions.IsAuthenticated, )
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
"""Override get_queryset method."""
|
"""Override get_queryset method."""
|
||||||
|
|
@ -135,3 +135,48 @@ class ProductSubTypeRUDBackOfficeView(BackOfficeListCreateMixin,
|
||||||
generics.RetrieveUpdateDestroyAPIView):
|
generics.RetrieveUpdateDestroyAPIView):
|
||||||
"""Product sub type back-office retrieve-update-destroy view."""
|
"""Product sub type back-office retrieve-update-destroy view."""
|
||||||
serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer
|
serializer_class = serializers.ProductSubTypeBackOfficeDetailSerializer
|
||||||
|
|
||||||
|
|
||||||
|
class ProductNoteListCreateView(ProductBackOfficeMixinView,
|
||||||
|
BackOfficeListCreateMixin,
|
||||||
|
generics.ListCreateAPIView):
|
||||||
|
"""Retrieve|Update|Destroy product note view."""
|
||||||
|
|
||||||
|
serializer_class = serializers.ProductNoteListCreateSerializer
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
"""Returns the object the view is displaying."""
|
||||||
|
product_qs = models.Product.objects.all()
|
||||||
|
filtered_product_qs = self.filter_queryset(product_qs)
|
||||||
|
|
||||||
|
product = get_object_or_404(filtered_product_qs, pk=self.kwargs['pk'])
|
||||||
|
|
||||||
|
# May raise a permission denied
|
||||||
|
self.check_object_permissions(self.request, product)
|
||||||
|
|
||||||
|
return product
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
"""Overridden get_queryset method."""
|
||||||
|
return self.get_object().notes.all()
|
||||||
|
|
||||||
|
|
||||||
|
class ProductNoteRUDView(ProductBackOfficeMixinView,
|
||||||
|
BackOfficeListCreateMixin,
|
||||||
|
generics.RetrieveUpdateDestroyAPIView):
|
||||||
|
"""Create|Retrieve|Update|Destroy product note view."""
|
||||||
|
|
||||||
|
serializer_class = serializers.ProductNoteBaseSerializer
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
"""Returns the object the view is displaying."""
|
||||||
|
product_qs = models.Product.objects.all()
|
||||||
|
filtered_product_qs = self.filter_queryset(product_qs)
|
||||||
|
|
||||||
|
product = get_object_or_404(filtered_product_qs, pk=self.kwargs['pk'])
|
||||||
|
note = get_object_or_404(product.notes.all(), pk=self.kwargs['note_pk'])
|
||||||
|
|
||||||
|
# May raise a permission denied
|
||||||
|
self.check_object_permissions(self.request, note)
|
||||||
|
|
||||||
|
return note
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user