Features: 1) RUFFVCKED
This commit is contained in:
parent
aa8f15d0ee
commit
29005527bb
15 changed files with 126 additions and 106 deletions
|
|
@ -9,6 +9,9 @@
|
||||||
<option name="TEMPLATE_FOLDERS">
|
<option name="TEMPLATE_FOLDERS">
|
||||||
<list>
|
<list>
|
||||||
<option value="$MODULE_DIR$/blog/templates" />
|
<option value="$MODULE_DIR$/blog/templates" />
|
||||||
|
<option value="$MODULE_DIR$/core/templates" />
|
||||||
|
<option value="$MODULE_DIR$/payments/templates" />
|
||||||
|
<option value="$MODULE_DIR$/vibes_auth/templates" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from markdown_field import MarkdownField
|
||||||
from core.abstract import NiceModel
|
from core.abstract import NiceModel
|
||||||
|
|
||||||
|
|
||||||
class Post(NiceModel):
|
class Post(NiceModel): # type: ignore [django-manager-missing]
|
||||||
"""
|
"""
|
||||||
Represents a blog post model extending NiceModel.
|
Represents a blog post model extending NiceModel.
|
||||||
|
|
||||||
|
|
@ -21,8 +21,8 @@ class Post(NiceModel):
|
||||||
Attributes:
|
Attributes:
|
||||||
is_publicly_visible (bool): Specifies whether the post is visible to the public.
|
is_publicly_visible (bool): Specifies whether the post is visible to the public.
|
||||||
author (ForeignKey): A reference to the user who authored the post.
|
author (ForeignKey): A reference to the user who authored the post.
|
||||||
title (CharField): The title of the post, must be unique and non-empty.
|
title (CharField): The title of the post. Must be unique and non-empty.
|
||||||
content (MarkdownField): The content of the post written in markdown format.
|
content (MarkdownField): The content of the post written in Markdown format.
|
||||||
file (FileField): An optional file attachment for the post.
|
file (FileField): An optional file attachment for the post.
|
||||||
slug (AutoSlugField): A unique, automatically generated slug based on the title.
|
slug (AutoSlugField): A unique, automatically generated slug based on the title.
|
||||||
tags (ManyToManyField): Tags associated with the post for categorization.
|
tags (ManyToManyField): Tags associated with the post for categorization.
|
||||||
|
|
@ -102,9 +102,9 @@ class PostTag(NiceModel):
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
is_publicly_visible (bool): Determines if the tag is visible publicly.
|
is_publicly_visible (bool): Determines if the tag is visible publicly.
|
||||||
tag_name (CharField): An internal tag identifier for the post tag. It is a required
|
tag_name (CharField): An internal tag identifier for the post's tag. It is a required
|
||||||
field with a maximum length of 255 characters.
|
field with a maximum length of 255 characters.
|
||||||
name (CharField): A user-friendly, unique display name for the post tag
|
name (CharField): A user-friendly, unique display name for the post's tag
|
||||||
with a maximum length of 255 characters.
|
with a maximum length of 255 characters.
|
||||||
|
|
||||||
Meta:
|
Meta:
|
||||||
|
|
|
||||||
|
|
@ -82,40 +82,17 @@ class FieldsetsMixin:
|
||||||
return fieldsets
|
return fieldsets
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnresolvedReferences
|
||||||
class ActivationActionsMixin:
|
class ActivationActionsMixin:
|
||||||
@action(description=str(_("activate selected %(verbose_name_plural)s")))
|
@action(description=_("activate selected %(verbose_name_plural)s"))
|
||||||
def activate_selected(self, request, queryset, **kwargs) -> str:
|
def activate_selected(self, request, queryset):
|
||||||
if kwargs:
|
|
||||||
pass
|
|
||||||
if request:
|
|
||||||
pass
|
|
||||||
queryset.update(is_active=True)
|
queryset.update(is_active=True)
|
||||||
return str(_("%(verbose_name_plural)s activated successfully!"))
|
self.message_user(request, _("selected items have been activated."))
|
||||||
|
|
||||||
@action(description=str(_("deactivate selected %(verbose_name_plural)s")))
|
@action(description=_("deactivate selected %(verbose_name_plural)s"))
|
||||||
def deactivate_selected(self, request, queryset, **kwargs) -> str:
|
def deactivate_selected(self, request, queryset):
|
||||||
if kwargs:
|
|
||||||
pass
|
|
||||||
if request:
|
|
||||||
pass
|
|
||||||
queryset.update(is_active=False)
|
queryset.update(is_active=False)
|
||||||
return str(_("%(verbose_name_plural)s deactivated successfully."))
|
self.message_user(request, _("selected items have been deactivated."))
|
||||||
|
|
||||||
def get_actions(self, request, **kwargs):
|
|
||||||
if kwargs:
|
|
||||||
pass
|
|
||||||
actions = super().get_actions(request)
|
|
||||||
actions["activate_selected"] = (
|
|
||||||
self.activate_selected,
|
|
||||||
"activate_selected",
|
|
||||||
str(_("activate selected %(verbose_name_plural)s")),
|
|
||||||
)
|
|
||||||
actions["deactivate_selected"] = (
|
|
||||||
self.deactivate_selected,
|
|
||||||
"deactivate_selected",
|
|
||||||
str(_("deactivate selected %(verbose_name_plural)s")),
|
|
||||||
)
|
|
||||||
return actions
|
|
||||||
|
|
||||||
|
|
||||||
class AttributeValueInline(TabularInline):
|
class AttributeValueInline(TabularInline):
|
||||||
|
|
@ -173,7 +150,8 @@ class CategoryChildrenInline(TabularInline):
|
||||||
|
|
||||||
@register(AttributeGroup)
|
@register(AttributeGroup)
|
||||||
class AttributeGroupAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class AttributeGroupAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = AttributeGroup
|
# noinspection PyClassVar
|
||||||
|
model = AttributeGroup # type: ignore [misc]
|
||||||
list_display = ("name", "modified")
|
list_display = ("name", "modified")
|
||||||
search_fields = ("uuid", "name")
|
search_fields = ("uuid", "name")
|
||||||
readonly_fields = ("uuid", "modified", "created")
|
readonly_fields = ("uuid", "modified", "created")
|
||||||
|
|
@ -184,7 +162,8 @@ class AttributeGroupAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Attribute)
|
@register(Attribute)
|
||||||
class AttributeAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class AttributeAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = Attribute
|
# noinspection PyClassVar
|
||||||
|
model = Attribute # type: ignore [misc]
|
||||||
list_display = ("name", "group", "value_type", "modified")
|
list_display = ("name", "group", "value_type", "modified")
|
||||||
list_filter = ("value_type", "group", "is_active")
|
list_filter = ("value_type", "group", "is_active")
|
||||||
search_fields = ("uuid", "name", "group__name")
|
search_fields = ("uuid", "name", "group__name")
|
||||||
|
|
@ -197,7 +176,8 @@ class AttributeAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(AttributeValue)
|
@register(AttributeValue)
|
||||||
class AttributeValueAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class AttributeValueAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = AttributeValue
|
# noinspection PyClassVar
|
||||||
|
model = AttributeValue # type: ignore [misc]
|
||||||
list_display = ("attribute", "value", "modified")
|
list_display = ("attribute", "value", "modified")
|
||||||
list_filter = ("attribute__group", "is_active")
|
list_filter = ("attribute__group", "is_active")
|
||||||
search_fields = ("uuid", "value", "attribute__name")
|
search_fields = ("uuid", "value", "attribute__name")
|
||||||
|
|
@ -210,6 +190,7 @@ class AttributeValueAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Category)
|
@register(Category)
|
||||||
class CategoryAdmin(FieldsetsMixin, ActivationActionsMixin, DraggableMPTTAdmin):
|
class CategoryAdmin(FieldsetsMixin, ActivationActionsMixin, DraggableMPTTAdmin):
|
||||||
|
# noinspection PyClassVar
|
||||||
model = Category
|
model = Category
|
||||||
list_display = ("indented_title", "parent", "is_active", "modified")
|
list_display = ("indented_title", "parent", "is_active", "modified")
|
||||||
# noinspection PyUnresolvedReferences
|
# noinspection PyUnresolvedReferences
|
||||||
|
|
@ -225,7 +206,8 @@ class CategoryAdmin(FieldsetsMixin, ActivationActionsMixin, DraggableMPTTAdmin):
|
||||||
|
|
||||||
@register(Brand)
|
@register(Brand)
|
||||||
class BrandAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class BrandAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = Brand
|
# noinspection PyClassVar
|
||||||
|
model = Brand # type: ignore [misc]
|
||||||
list_display = ("name",)
|
list_display = ("name",)
|
||||||
list_filter = ("categories", "is_active")
|
list_filter = ("categories", "is_active")
|
||||||
search_fields = ("uuid", "name", "categories__name")
|
search_fields = ("uuid", "name", "categories__name")
|
||||||
|
|
@ -237,7 +219,8 @@ class BrandAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Product)
|
@register(Product)
|
||||||
class ProductAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class ProductAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = Product
|
# noinspection PyClassVar
|
||||||
|
model = Product # type: ignore [misc]
|
||||||
list_display = (
|
list_display = (
|
||||||
"name",
|
"name",
|
||||||
"partnumber",
|
"partnumber",
|
||||||
|
|
@ -276,7 +259,8 @@ class ProductAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(ProductTag)
|
@register(ProductTag)
|
||||||
class ProductTagAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class ProductTagAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = ProductTag
|
# noinspection PyClassVar
|
||||||
|
model = ProductTag # type: ignore [misc]
|
||||||
list_display = ("tag_name",)
|
list_display = ("tag_name",)
|
||||||
search_fields = ("tag_name",)
|
search_fields = ("tag_name",)
|
||||||
readonly_fields = ("uuid", "modified", "created")
|
readonly_fields = ("uuid", "modified", "created")
|
||||||
|
|
@ -287,7 +271,8 @@ class ProductTagAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(CategoryTag)
|
@register(CategoryTag)
|
||||||
class CategoryTagAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class CategoryTagAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = CategoryTag
|
# noinspection PyClassVar
|
||||||
|
model = CategoryTag # type: ignore [misc]
|
||||||
list_display = ("tag_name",)
|
list_display = ("tag_name",)
|
||||||
search_fields = ("tag_name",)
|
search_fields = ("tag_name",)
|
||||||
readonly_fields = ("uuid", "modified", "created")
|
readonly_fields = ("uuid", "modified", "created")
|
||||||
|
|
@ -298,7 +283,8 @@ class CategoryTagAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Vendor)
|
@register(Vendor)
|
||||||
class VendorAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class VendorAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = Vendor
|
# noinspection PyClassVar
|
||||||
|
model = Vendor # type: ignore [misc]
|
||||||
list_display = ("name", "markup_percent", "modified")
|
list_display = ("name", "markup_percent", "modified")
|
||||||
list_filter = ("markup_percent", "is_active")
|
list_filter = ("markup_percent", "is_active")
|
||||||
search_fields = ("name",)
|
search_fields = ("name",)
|
||||||
|
|
@ -311,7 +297,8 @@ class VendorAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Feedback)
|
@register(Feedback)
|
||||||
class FeedbackAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class FeedbackAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = Feedback
|
# noinspection PyClassVar
|
||||||
|
model = Feedback # type: ignore [misc]
|
||||||
list_display = ("order_product", "rating", "comment", "modified")
|
list_display = ("order_product", "rating", "comment", "modified")
|
||||||
list_filter = ("rating", "is_active")
|
list_filter = ("rating", "is_active")
|
||||||
search_fields = ("order_product__product__name", "comment")
|
search_fields = ("order_product__product__name", "comment")
|
||||||
|
|
@ -323,7 +310,8 @@ class FeedbackAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Order)
|
@register(Order)
|
||||||
class OrderAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class OrderAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = Order
|
# noinspection PyClassVar
|
||||||
|
model = Order # type: ignore [misc]
|
||||||
list_display = (
|
list_display = (
|
||||||
"human_readable_id",
|
"human_readable_id",
|
||||||
"user",
|
"user",
|
||||||
|
|
@ -351,7 +339,8 @@ class OrderAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(OrderProduct)
|
@register(OrderProduct)
|
||||||
class OrderProductAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class OrderProductAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = OrderProduct
|
# noinspection PyClassVar
|
||||||
|
model = OrderProduct # type: ignore [misc]
|
||||||
list_display = ("order", "product", "quantity", "buy_price", "status", "modified")
|
list_display = ("order", "product", "quantity", "buy_price", "status", "modified")
|
||||||
list_filter = ("status",)
|
list_filter = ("status",)
|
||||||
search_fields = ("order__user__email", "product__name")
|
search_fields = ("order__user__email", "product__name")
|
||||||
|
|
@ -364,7 +353,8 @@ class OrderProductAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(PromoCode)
|
@register(PromoCode)
|
||||||
class PromoCodeAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class PromoCodeAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = PromoCode
|
# noinspection PyClassVar
|
||||||
|
model = PromoCode # type: ignore [misc]
|
||||||
list_display = (
|
list_display = (
|
||||||
"code",
|
"code",
|
||||||
"discount_percent",
|
"discount_percent",
|
||||||
|
|
@ -392,7 +382,8 @@ class PromoCodeAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Promotion)
|
@register(Promotion)
|
||||||
class PromotionAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class PromotionAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = Promotion
|
# noinspection PyClassVar
|
||||||
|
model = Promotion # type: ignore [misc]
|
||||||
list_display = ("name", "discount_percent", "modified")
|
list_display = ("name", "discount_percent", "modified")
|
||||||
search_fields = ("name",)
|
search_fields = ("name",)
|
||||||
readonly_fields = ("uuid", "modified", "created")
|
readonly_fields = ("uuid", "modified", "created")
|
||||||
|
|
@ -404,7 +395,8 @@ class PromotionAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Stock)
|
@register(Stock)
|
||||||
class StockAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class StockAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = Stock
|
# noinspection PyClassVar
|
||||||
|
model = Stock # type: ignore [misc]
|
||||||
list_display = ("product", "vendor", "sku", "quantity", "price", "modified")
|
list_display = ("product", "vendor", "sku", "quantity", "price", "modified")
|
||||||
list_filter = ("vendor", "quantity")
|
list_filter = ("vendor", "quantity")
|
||||||
search_fields = ("product__name", "vendor__name", "sku")
|
search_fields = ("product__name", "vendor__name", "sku")
|
||||||
|
|
@ -424,7 +416,8 @@ class StockAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Wishlist)
|
@register(Wishlist)
|
||||||
class WishlistAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class WishlistAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = Wishlist
|
# noinspection PyClassVar
|
||||||
|
model = Wishlist # type: ignore [misc]
|
||||||
list_display = ("user", "modified")
|
list_display = ("user", "modified")
|
||||||
search_fields = ("user__email",)
|
search_fields = ("user__email",)
|
||||||
readonly_fields = ("uuid", "modified", "created")
|
readonly_fields = ("uuid", "modified", "created")
|
||||||
|
|
@ -435,7 +428,8 @@ class WishlistAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(ProductImage)
|
@register(ProductImage)
|
||||||
class ProductImageAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
class ProductImageAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
model = ProductImage
|
# noinspection PyClassVar
|
||||||
|
model = ProductImage # type: ignore [misc]
|
||||||
list_display = ("alt", "product", "priority", "modified")
|
list_display = ("alt", "product", "priority", "modified")
|
||||||
list_filter = ("priority",)
|
list_filter = ("priority",)
|
||||||
search_fields = ("alt", "product__name")
|
search_fields = ("alt", "product__name")
|
||||||
|
|
@ -448,7 +442,8 @@ class ProductImageAdmin(FieldsetsMixin, ActivationActionsMixin, ModelAdmin):
|
||||||
|
|
||||||
@register(Address)
|
@register(Address)
|
||||||
class AddressAdmin(FieldsetsMixin, GISModelAdmin):
|
class AddressAdmin(FieldsetsMixin, GISModelAdmin):
|
||||||
model = Address
|
# noinspection PyClassVar
|
||||||
|
model = Address # type: ignore [misc]
|
||||||
list_display = ("street", "city", "region", "country", "user")
|
list_display = ("street", "city", "region", "country", "user")
|
||||||
list_filter = ("country", "region")
|
list_filter = ("country", "region")
|
||||||
search_fields = ("street", "city", "postal_code", "user__email")
|
search_fields = ("street", "city", "postal_code", "user__email")
|
||||||
|
|
@ -511,7 +506,7 @@ class ConstanceConfig:
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
site.unregister([Config])
|
site.unregister([Config])
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
site.register([ConstanceConfig], BaseConstanceAdmin)
|
site.register([ConstanceConfig], BaseConstanceAdmin) # type: ignore [list-item]
|
||||||
site.site_title = CONSTANCE_CONFIG["PROJECT_NAME"][0]
|
site.site_title = CONSTANCE_CONFIG["PROJECT_NAME"][0] # type: ignore [assignment]
|
||||||
site.site_header = "eVibes"
|
site.site_header = "eVibes"
|
||||||
site.index_title = CONSTANCE_CONFIG["PROJECT_NAME"][0]
|
site.index_title = CONSTANCE_CONFIG["PROJECT_NAME"][0] # type: ignore [assignment]
|
||||||
|
|
|
||||||
|
|
@ -860,7 +860,7 @@ class ProductImage(ExportModelOperationsMixin("product_image"), NiceModel): # t
|
||||||
image (ImageField): The image file associated with the product.
|
image (ImageField): The image file associated with the product.
|
||||||
priority (int): The display priority of the image. Images with lower
|
priority (int): The display priority of the image. Images with lower
|
||||||
priority values are displayed first.
|
priority values are displayed first.
|
||||||
product (ForeignKey): The product to which this image is associated.
|
product (ForeignKey): The product associated with this image.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
is_publicly_visible = True
|
is_publicly_visible = True
|
||||||
|
|
@ -1278,11 +1278,11 @@ class PromoCode(ExportModelOperationsMixin("promocode"), NiceModel): # type: ig
|
||||||
promo_amount = order.total_price
|
promo_amount = order.total_price
|
||||||
|
|
||||||
if self.discount_type == "percent":
|
if self.discount_type == "percent":
|
||||||
promo_amount -= round(promo_amount * (float(self.discount_percent) / 100), 2)
|
promo_amount -= round(promo_amount * (float(self.discount_percent) / 100), 2) # type: ignore [arg-type]
|
||||||
order.attributes.update({"promocode": str(self.uuid), "final_price": promo_amount})
|
order.attributes.update({"promocode": str(self.uuid), "final_price": promo_amount})
|
||||||
order.save()
|
order.save()
|
||||||
elif self.discount_type == "amount":
|
elif self.discount_type == "amount":
|
||||||
promo_amount -= round(float(self.discount_amount), 2)
|
promo_amount -= round(float(self.discount_amount), 2) # type: ignore [arg-type]
|
||||||
order.attributes.update({"promocode": str(self.uuid), "final_price": promo_amount})
|
order.attributes.update({"promocode": str(self.uuid), "final_price": promo_amount})
|
||||||
order.save()
|
order.save()
|
||||||
else:
|
else:
|
||||||
|
|
@ -1447,7 +1447,7 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
|
||||||
promotions = Promotion.objects.filter(is_active=True, products__in=[product]).order_by("discount_percent")
|
promotions = Promotion.objects.filter(is_active=True, products__in=[product]).order_by("discount_percent")
|
||||||
|
|
||||||
if promotions.exists():
|
if promotions.exists():
|
||||||
buy_price -= round(product.price * (promotions.first().discount_percent / 100), 2)
|
buy_price -= round(product.price * (promotions.first().discount_percent / 100), 2) # type: ignore [union-attr]
|
||||||
|
|
||||||
order_product, is_created = OrderProduct.objects.get_or_create(
|
order_product, is_created = OrderProduct.objects.get_or_create(
|
||||||
product=product,
|
product=product,
|
||||||
|
|
@ -1588,6 +1588,12 @@ class Order(ExportModelOperationsMixin("order"), NiceModel): # type: ignore [mi
|
||||||
|
|
||||||
amount = self.apply_promocode(promocode_uuid) if promocode_uuid else self.total_price
|
amount = self.apply_promocode(promocode_uuid) if promocode_uuid else self.total_price
|
||||||
|
|
||||||
|
if not self.user:
|
||||||
|
raise ValueError(_("you cannot buy an order without a user"))
|
||||||
|
|
||||||
|
if not self.user.payments_balance:
|
||||||
|
raise ValueError(_("a user without a balance cannot buy with balance"))
|
||||||
|
|
||||||
match force:
|
match force:
|
||||||
case "balance":
|
case "balance":
|
||||||
if self.user.payments_balance.amount < amount:
|
if self.user.payments_balance.amount < amount:
|
||||||
|
|
@ -1786,7 +1792,10 @@ class OrderProduct(ExportModelOperationsMixin("order_product"), NiceModel): # t
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"{self.product.name} for ({self.order.user.email if self.order.user else 'unregistered user'})"
|
return (
|
||||||
|
f"{self.product.name if self.product else self.uuid}"
|
||||||
|
f" for ({self.order.user.email if self.order and self.order.user else 'unregistered user'})"
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("order product")
|
verbose_name = _("order product")
|
||||||
|
|
@ -1827,16 +1836,18 @@ class OrderProduct(ExportModelOperationsMixin("order_product"), NiceModel): # t
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def total_price(self: Self) -> float:
|
def total_price(self: Self) -> float:
|
||||||
return round(float(self.buy_price) * self.quantity, 2)
|
return round(float(self.buy_price) * self.quantity, 2) # type: ignore [arg-type]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def download_url(self: Self) -> str:
|
def download_url(self: Self) -> str:
|
||||||
if self.product:
|
if self.product and self.product.stocks:
|
||||||
if self.product.is_digital and self.product.stocks.first().digital_asset:
|
if self.product.is_digital and self.product.stocks.first().digital_asset: # type: ignore [union-attr]
|
||||||
return self.download.url
|
return self.download.url
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def do_feedback(self, rating=10, comment="", action="add") -> Optional["Feedback"]:
|
def do_feedback(self, rating=10, comment="", action="add") -> Optional["Feedback"]:
|
||||||
|
if not self.order:
|
||||||
|
raise ValueError(_("order product must have an order"))
|
||||||
if action not in ["add", "remove"]:
|
if action not in ["add", "remove"]:
|
||||||
raise ValueError(_(f"wrong action specified for feedback: {action}"))
|
raise ValueError(_(f"wrong action specified for feedback: {action}"))
|
||||||
if action == "remove" and self.feedback:
|
if action == "remove" and self.feedback:
|
||||||
|
|
@ -1904,7 +1915,7 @@ class Feedback(ExportModelOperationsMixin("feedback"), NiceModel): # type: igno
|
||||||
This class is designed to capture and store user feedback for specific products
|
This class is designed to capture and store user feedback for specific products
|
||||||
that they have purchased. It contains attributes to store user comments,
|
that they have purchased. It contains attributes to store user comments,
|
||||||
a reference to the related product in the order, and a user-assigned rating. The
|
a reference to the related product in the order, and a user-assigned rating. The
|
||||||
class utilizes database fields to effectively model and manage feedback data.
|
class uses database fields to effectively model and manage feedback data.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
is_publicly_visible (bool): Indicates whether the feedback is visible to the public.
|
is_publicly_visible (bool): Indicates whether the feedback is visible to the public.
|
||||||
|
|
@ -1940,7 +1951,9 @@ class Feedback(ExportModelOperationsMixin("feedback"), NiceModel): # type: igno
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
|
if self.order_product and self.order_product.order and self.order_product.order.user:
|
||||||
return f"{self.rating} by {self.order_product.order.user.email}"
|
return f"{self.rating} by {self.order_product.order.user.email}"
|
||||||
|
return f"{self.rating} | {self.uuid}"
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _("feedback")
|
verbose_name = _("feedback")
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
|
from typing import Collection, Any
|
||||||
|
|
||||||
from rest_framework.fields import JSONField, SerializerMethodField
|
from rest_framework.fields import JSONField, SerializerMethodField
|
||||||
from rest_framework.relations import PrimaryKeyRelatedField
|
from rest_framework.relations import PrimaryKeyRelatedField
|
||||||
|
|
@ -26,8 +27,8 @@ from core.serializers.utility import AddressSerializer
|
||||||
|
|
||||||
|
|
||||||
class AttributeGroupSimpleSerializer(ModelSerializer):
|
class AttributeGroupSimpleSerializer(ModelSerializer):
|
||||||
parent = PrimaryKeyRelatedField(read_only=True)
|
parent = PrimaryKeyRelatedField(read_only=True) # type: ignore [assignment, var-annotated]
|
||||||
children = PrimaryKeyRelatedField(many=True, read_only=True)
|
children = PrimaryKeyRelatedField(many=True, read_only=True) # type: ignore [assignment, var-annotated]
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = AttributeGroup
|
model = AttributeGroup
|
||||||
|
|
@ -58,7 +59,7 @@ class CategorySimpleSerializer(ModelSerializer):
|
||||||
return obj.image.url
|
return obj.image.url
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_children(self, obj) -> list:
|
def get_children(self, obj) -> Collection[Any]:
|
||||||
request = self.context.get("request")
|
request = self.context.get("request")
|
||||||
if request is not None and request.user.has_perm("view_category"):
|
if request is not None and request.user.has_perm("view_category"):
|
||||||
children = obj.children.all()
|
children = obj.children.all()
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ class DoFeedbackSerializer(Serializer):
|
||||||
|
|
||||||
class CacheOperatorSerializer(Serializer):
|
class CacheOperatorSerializer(Serializer):
|
||||||
key = CharField(required=True)
|
key = CharField(required=True)
|
||||||
data = JSONField(required=False)
|
data = JSONField(required=False) # type: ignore [assignment]
|
||||||
timeout = IntegerField(required=False)
|
timeout = IntegerField(required=False)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,9 @@ def send_order_finished_email(order_pk: str) -> tuple[bool, str]:
|
||||||
if len(ops) <= 0:
|
if len(ops) <= 0:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
if not order.user:
|
||||||
|
return
|
||||||
|
|
||||||
activate(order.user.language)
|
activate(order.user.language)
|
||||||
|
|
||||||
set_email_settings()
|
set_email_settings()
|
||||||
|
|
@ -94,11 +97,11 @@ def send_order_finished_email(order_pk: str) -> tuple[bool, str]:
|
||||||
template_name="digital_order_delivered_email.html",
|
template_name="digital_order_delivered_email.html",
|
||||||
context={
|
context={
|
||||||
"order_uuid": order.human_readable_id,
|
"order_uuid": order.human_readable_id,
|
||||||
"user_first_name": order.user.first_name,
|
"user_first_name": "" or order.user.first_name,
|
||||||
"order_products": ops,
|
"order_products": ops,
|
||||||
"project_name": config.PROJECT_NAME,
|
"project_name": config.PROJECT_NAME,
|
||||||
"contact_email": config.EMAIL_FROM,
|
"contact_email": config.EMAIL_FROM,
|
||||||
"total_price": round(sum(op.buy_price for op in ops), 2),
|
"total_price": round(sum(0.0 or op.buy_price for op in ops), 2), # type: ignore [misc]
|
||||||
"display_system_attributes": order.user.has_perm("core.view_order"),
|
"display_system_attributes": order.user.has_perm("core.view_order"),
|
||||||
"today": datetime.today(),
|
"today": datetime.today(),
|
||||||
},
|
},
|
||||||
|
|
@ -113,6 +116,8 @@ def send_order_finished_email(order_pk: str) -> tuple[bool, str]:
|
||||||
def send_thank_you_email(ops: list[OrderProduct]):
|
def send_thank_you_email(ops: list[OrderProduct]):
|
||||||
if ops:
|
if ops:
|
||||||
pass
|
pass
|
||||||
|
if not order.user:
|
||||||
|
return
|
||||||
activate(order.user.language)
|
activate(order.user.language)
|
||||||
|
|
||||||
set_email_settings()
|
set_email_settings()
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ class SupportedLanguagesView(APIView):
|
||||||
"""
|
"""
|
||||||
Handles retrieving the list of supported languages.
|
Handles retrieving the list of supported languages.
|
||||||
|
|
||||||
This class provides an endpoint to return available languages information.
|
This class provides an endpoint to return information about available languages.
|
||||||
It is configured with relevant serializers, permission classes, and renderers
|
It is configured with relevant serializers, permission classes, and renderers
|
||||||
for flexibility in response formats and access permissions. The endpoint
|
for flexibility in response formats and access permissions. The endpoint
|
||||||
supports retrieving the list of languages with their respective codes, names,
|
supports retrieving the list of languages with their respective codes, names,
|
||||||
|
|
@ -328,7 +328,8 @@ class RequestCursedURLView(APIView):
|
||||||
renderer_classes (list): Configures the response format renderers available for this view.
|
renderer_classes (list): Configures the response format renderers available for this view.
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
post: Handles the POST request to validate the URL, fetch its data if valid, and returns the processed response.
|
post: Handles the POST request to validate the URL, fetches its data if valid,
|
||||||
|
and returns the processed response.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = [
|
permission_classes = [
|
||||||
|
|
|
||||||
|
|
@ -245,7 +245,7 @@ class CategoryViewSet(EvibesViewSet):
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
queryset: The base queryset used to retrieve category data, including
|
queryset: The base queryset used to retrieve category data, including
|
||||||
prefetching related objects such as parent, children, attributes,
|
prefetching related objects such as parents, children, attributes,
|
||||||
and tags.
|
and tags.
|
||||||
filter_backends: A list of backends for applying filters to the category
|
filter_backends: A list of backends for applying filters to the category
|
||||||
data.
|
data.
|
||||||
|
|
@ -315,8 +315,8 @@ class ProductViewSet(EvibesViewSet):
|
||||||
Manages operations related to the `Product` model in the system.
|
Manages operations related to the `Product` model in the system.
|
||||||
|
|
||||||
This class provides a viewset for managing products, including their filtering, serialization,
|
This class provides a viewset for managing products, including their filtering, serialization,
|
||||||
and operations on specific instances. It extends from `EvibesViewSet` to utilize common
|
and operations on specific instances. It extends from `EvibesViewSet` to use common
|
||||||
functionality and integrates with Django REST framework for RESTful API operations.
|
functionality and integrates with the Django REST framework for RESTful API operations.
|
||||||
Includes methods for retrieving product details, applying permissions, and accessing
|
Includes methods for retrieving product details, applying permissions, and accessing
|
||||||
related feedback of a product.
|
related feedback of a product.
|
||||||
|
|
||||||
|
|
@ -383,6 +383,7 @@ class ProductViewSet(EvibesViewSet):
|
||||||
if request.user.has_perm("core.view_feedback")
|
if request.user.has_perm("core.view_feedback")
|
||||||
else Feedback.objects.filter(order_product__product=product, is_active=True)
|
else Feedback.objects.filter(order_product__product=product, is_active=True)
|
||||||
)
|
)
|
||||||
|
# noinspection PyTypeChecker
|
||||||
return Response(data=FeedbackDetailSerializer(feedbacks, many=True).data)
|
return Response(data=FeedbackDetailSerializer(feedbacks, many=True).data)
|
||||||
except Product.DoesNotExist:
|
except Product.DoesNotExist:
|
||||||
name = "Product"
|
name = "Product"
|
||||||
|
|
@ -784,7 +785,7 @@ class PromoCodeViewSet(EvibesViewSet):
|
||||||
|
|
||||||
This class extends the functionality of the EvibesViewSet to provide a
|
This class extends the functionality of the EvibesViewSet to provide a
|
||||||
customized view set for PromoCode objects. It includes filtering capabilities,
|
customized view set for PromoCode objects. It includes filtering capabilities,
|
||||||
utilizes specific serializers for different actions, and limits data access
|
uses specific serializers for different actions, and limits data access
|
||||||
based on user permissions. The primary purpose is to enable API operations
|
based on user permissions. The primary purpose is to enable API operations
|
||||||
related to PromoCodes while enforcing security and filtering.
|
related to PromoCodes while enforcing security and filtering.
|
||||||
|
|
||||||
|
|
@ -840,7 +841,7 @@ class StockViewSet(EvibesViewSet):
|
||||||
Handles operations related to Stock data in the system.
|
Handles operations related to Stock data in the system.
|
||||||
|
|
||||||
The StockViewSet class is a viewset that provides methods for retrieving,
|
The StockViewSet class is a viewset that provides methods for retrieving,
|
||||||
filtering, and serializing Stock data. It utilizes Django's filter
|
filtering, and serializing Stock data. It uses Django's filter
|
||||||
backends to enable filtering based on specified fields and supports
|
backends to enable filtering based on specified fields and supports
|
||||||
custom serializers for different actions.
|
custom serializers for different actions.
|
||||||
|
|
||||||
|
|
@ -875,7 +876,7 @@ class WishlistViewSet(EvibesViewSet):
|
||||||
allowing for the retrieval, modification, and customization of products within
|
allowing for the retrieval, modification, and customization of products within
|
||||||
the wish list. This ViewSet facilitates functionality such as adding, removing,
|
the wish list. This ViewSet facilitates functionality such as adding, removing,
|
||||||
and bulk actions for wishlist products. Permission checks are integrated to
|
and bulk actions for wishlist products. Permission checks are integrated to
|
||||||
ensure that users can only manage their own wishlists, unless explicit permissions
|
ensure that users can only manage their own wishlists unless explicit permissions
|
||||||
are granted.
|
are granted.
|
||||||
|
|
||||||
Attributes
|
Attributes
|
||||||
|
|
@ -1096,10 +1097,10 @@ class ProductTagViewSet(EvibesViewSet):
|
||||||
filterset_fields: Fields available for filtering the queryset. Includes
|
filterset_fields: Fields available for filtering the queryset. Includes
|
||||||
'tag_name' for filtering by the name of the tag, and 'is_active' for
|
'tag_name' for filtering by the name of the tag, and 'is_active' for
|
||||||
filtering active/inactive tags.
|
filtering active/inactive tags.
|
||||||
serializer_class: The default serializer class used when no specific
|
serializer_class: The default serializer class is used when no specific
|
||||||
serializer is defined for an action.
|
serializer is defined for an action.
|
||||||
action_serializer_classes: A dictionary mapping specific actions (e.g.,
|
action_serializer_classes: A dictionary mapping specific actions (e.g.,
|
||||||
'list') to custom serializers. Utilizes ProductTagSimpleSerializer
|
'list') to custom serializers. Uses ProductTagSimpleSerializer
|
||||||
for the 'list' action.
|
for the 'list' action.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ CURRENCIES: tuple[tuple[str, str], ...] = (
|
||||||
("zh-hans", "CNY"),
|
("zh-hans", "CNY"),
|
||||||
)
|
)
|
||||||
|
|
||||||
CURRENCY_CODE: str | None = dict(CURRENCIES).get(LANGUAGE_CODE)
|
CURRENCY_CODE: str = dict(CURRENCIES).get(LANGUAGE_CODE) # type: ignore [assignment]
|
||||||
|
|
||||||
MODELTRANSLATION_FALLBACK_LANGUAGES: tuple = (LANGUAGE_CODE, "en-us", "de-de")
|
MODELTRANSLATION_FALLBACK_LANGUAGES: tuple = (LANGUAGE_CODE, "en-us", "de-de")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
from evibes.settings import CONSTANCE_CONFIG
|
from evibes.settings import CONSTANCE_CONFIG
|
||||||
|
|
||||||
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
|
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
|
||||||
EMAIL_HOST = CONSTANCE_CONFIG.get("EMAIL_HOST")[0]
|
EMAIL_HOST = CONSTANCE_CONFIG.get("EMAIL_HOST")[0] # type: ignore [index]
|
||||||
EMAIL_PORT = CONSTANCE_CONFIG.get("EMAIL_PORT")[0]
|
EMAIL_PORT = CONSTANCE_CONFIG.get("EMAIL_PORT")[0] # type: ignore [index]
|
||||||
EMAIL_USE_TLS = CONSTANCE_CONFIG.get("EMAIL_USE_TLS")[0]
|
EMAIL_USE_TLS = CONSTANCE_CONFIG.get("EMAIL_USE_TLS")[0] # type: ignore [index]
|
||||||
EMAIL_USE_SSL = CONSTANCE_CONFIG.get("EMAIL_USE_SSL")[0]
|
EMAIL_USE_SSL = CONSTANCE_CONFIG.get("EMAIL_USE_SSL")[0] # type: ignore [index]
|
||||||
EMAIL_HOST_USER = CONSTANCE_CONFIG.get("EMAIL_HOST_USER")[0]
|
EMAIL_HOST_USER = CONSTANCE_CONFIG.get("EMAIL_HOST_USER")[0] # type: ignore [index]
|
||||||
EMAIL_HOST_PASSWORD = CONSTANCE_CONFIG.get("EMAIL_HOST_PASSWORD")[0]
|
EMAIL_HOST_PASSWORD = CONSTANCE_CONFIG.get("EMAIL_HOST_PASSWORD")[0] # type: ignore [index]
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ from payments.serializers import TransactionSerializer
|
||||||
|
|
||||||
class TransactionViewSet(ReadOnlyModelViewSet):
|
class TransactionViewSet(ReadOnlyModelViewSet):
|
||||||
"""
|
"""
|
||||||
ViewSet for handling read-only operations on Transaction model.
|
ViewSet for handling read-only operations on the Transaction model.
|
||||||
|
|
||||||
This class provides a read-only interface for interacting with transaction
|
This class provides a read-only interface for interacting with transaction
|
||||||
data. It utilizes the TransactionSerializer for serializing and deserializing
|
data. It uses the TransactionSerializer for serializing and deserializing
|
||||||
the data. The class ensures that only authorized users, who meet specific
|
the data. The class ensures that only authorized users, who meet specific
|
||||||
permissions, can access the transactions.
|
permissions, can access the transactions.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,6 @@ from rest_framework_simplejwt.token_blacklist.models import (
|
||||||
OutstandingToken as BaseOutstandingToken,
|
OutstandingToken as BaseOutstandingToken,
|
||||||
)
|
)
|
||||||
|
|
||||||
from blog.models import Post
|
|
||||||
from core.abstract import NiceModel
|
from core.abstract import NiceModel
|
||||||
from core.models import Order, Wishlist
|
from core.models import Order, Wishlist
|
||||||
from evibes.settings import LANGUAGE_CODE, LANGUAGES
|
from evibes.settings import LANGUAGE_CODE, LANGUAGES
|
||||||
|
|
@ -29,7 +28,7 @@ from vibes_auth.managers import UserManager
|
||||||
from vibes_auth.validators import validate_phone_number
|
from vibes_auth.validators import validate_phone_number
|
||||||
|
|
||||||
|
|
||||||
class User(AbstractUser, NiceModel):
|
class User(AbstractUser, NiceModel): # type: ignore [django-manager-missing]
|
||||||
"""
|
"""
|
||||||
Represents a User entity with customized fields and methods for extended functionality.
|
Represents a User entity with customized fields and methods for extended functionality.
|
||||||
|
|
||||||
|
|
@ -54,9 +53,9 @@ class User(AbstractUser, NiceModel):
|
||||||
attributes: JSONField for custom storage of user-specific additional attributes.
|
attributes: JSONField for custom storage of user-specific additional attributes.
|
||||||
USERNAME_FIELD: Specifies the unique identifier for the user (email in this case).
|
USERNAME_FIELD: Specifies the unique identifier for the user (email in this case).
|
||||||
REQUIRED_FIELDS: A list of fields required when creating a user via createsuperuser, left empty here.
|
REQUIRED_FIELDS: A list of fields required when creating a user via createsuperuser, left empty here.
|
||||||
objects: Custom manager for User model providing additional methods for user creation.
|
objects: Custom manager for the User model providing additional methods for user creation.
|
||||||
payments_balance: Reference to the user's payment balance (related to external model).
|
payments_balance: Reference to the user's payment balance (related to the external model).
|
||||||
user_related_wishlist: Reference to the user's wishlist (related to external model).
|
user_related_wishlist: Reference to the user's wishlist (related to the external model).
|
||||||
orders: QuerySet representing the user's associated orders.
|
orders: QuerySet representing the user's associated orders.
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
|
|
@ -96,7 +95,6 @@ class User(AbstractUser, NiceModel):
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
username: None = None # type: ignore [assignment]
|
username: None = None # type: ignore [assignment]
|
||||||
posts: "Post"
|
|
||||||
first_name = CharField(_("first_name"), max_length=150, blank=True, null=True) # type: ignore [assignment]
|
first_name = CharField(_("first_name"), max_length=150, blank=True, null=True) # type: ignore [assignment]
|
||||||
last_name = CharField(_("last_name"), max_length=150, blank=True, null=True) # type: ignore [assignment]
|
last_name = CharField(_("last_name"), max_length=150, blank=True, null=True) # type: ignore [assignment]
|
||||||
avatar = ImageField(
|
avatar = ImageField(
|
||||||
|
|
@ -207,7 +205,7 @@ class BlacklistedToken(BaseBlacklistedToken):
|
||||||
blacklisted tokens. It inherits from a base class provided for this purpose,
|
blacklisted tokens. It inherits from a base class provided for this purpose,
|
||||||
allowing for the extension of functionality or customization of behavior
|
allowing for the extension of functionality or customization of behavior
|
||||||
without altering the original base class's structure. It also defines the
|
without altering the original base class's structure. It also defines the
|
||||||
meta options for the model, affecting its database and administrative
|
Meta options for the model, affecting its database and administrative
|
||||||
representation.
|
representation.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,10 @@ class TokenObtainPairSerializer(TokenObtainSerializer):
|
||||||
logger.debug("Data formed")
|
logger.debug("Data formed")
|
||||||
|
|
||||||
if api_settings.UPDATE_LAST_LOGIN:
|
if api_settings.UPDATE_LAST_LOGIN:
|
||||||
update_last_login(self.user, self.user)
|
if not self.user:
|
||||||
|
raise ValidationError(_("no active account"))
|
||||||
|
# noinspection PyTypeChecker
|
||||||
|
update_last_login(User, self.user)
|
||||||
logger.debug("Updated last login")
|
logger.debug("Updated last login")
|
||||||
|
|
||||||
logger.debug("Returning data")
|
logger.debug("Returning data")
|
||||||
|
|
@ -191,7 +194,7 @@ class TokenRefreshSerializer(Serializer):
|
||||||
data["refresh"] = str(refresh)
|
data["refresh"] = str(refresh)
|
||||||
user = User.objects.get(uuid=refresh.payload["user_uuid"])
|
user = User.objects.get(uuid=refresh.payload["user_uuid"])
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
data["user"] = UserSerializer(user).data
|
data["user"] = UserSerializer(user).data # type: ignore [assignment]
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
@ -224,7 +227,7 @@ class TokenVerifySerializer(Serializer):
|
||||||
raise ValidationError(_("user does not exist")) from dne
|
raise ValidationError(_("user does not exist")) from dne
|
||||||
|
|
||||||
# noinspection PyTypeChecker
|
# noinspection PyTypeChecker
|
||||||
attrs["user"] = UserSerializer(user).data
|
attrs["user"] = UserSerializer(user).data # type: ignore [assignment]
|
||||||
return attrs
|
return attrs
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,8 @@ class TokenObtainPairView(TokenViewBase):
|
||||||
subject to rate limiting depending on the global DEBUG setting.
|
subject to rate limiting depending on the global DEBUG setting.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = TokenObtainPairSerializer
|
serializer_class = TokenObtainPairSerializer # type: ignore [assignment]
|
||||||
_serializer_class = TokenObtainPairSerializer
|
_serializer_class = TokenObtainPairSerializer # type: ignore [assignment]
|
||||||
|
|
||||||
@method_decorator(ratelimit(key="ip", rate="10/h" if not DEBUG else "888/h"))
|
@method_decorator(ratelimit(key="ip", rate="10/h" if not DEBUG else "888/h"))
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
|
@ -82,8 +82,8 @@ class TokenRefreshView(TokenViewBase):
|
||||||
whether the application is in DEBUG mode or not.
|
whether the application is in DEBUG mode or not.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = TokenRefreshSerializer
|
serializer_class = TokenRefreshSerializer # type: ignore [assignment]
|
||||||
_serializer_class = TokenRefreshSerializer
|
_serializer_class = TokenRefreshSerializer # type: ignore [assignment]
|
||||||
|
|
||||||
@method_decorator(ratelimit(key="ip", rate="10/h" if not DEBUG else "888/h"))
|
@method_decorator(ratelimit(key="ip", rate="10/h" if not DEBUG else "888/h"))
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
|
|
@ -104,8 +104,8 @@ class TokenVerifyView(TokenViewBase):
|
||||||
error response.
|
error response.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
serializer_class = TokenVerifySerializer
|
serializer_class = TokenVerifySerializer # type: ignore [assignment]
|
||||||
_serializer_class = TokenVerifySerializer
|
_serializer_class = TokenVerifySerializer # type: ignore [assignment]
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue