feat: added categories
This commit is contained in:
+15
-2
@@ -5,16 +5,17 @@ from shop.models import (
|
||||
Brand,
|
||||
Cart,
|
||||
CartItem,
|
||||
CustomerAddress,
|
||||
Order,
|
||||
OrderLine,
|
||||
Product,
|
||||
ProductBatch,
|
||||
ProductCategory,
|
||||
ProductPrice,
|
||||
Provider,
|
||||
ShippingMethod,
|
||||
Tag,
|
||||
Tax,
|
||||
ShippingMethod,
|
||||
CustomerAddress,
|
||||
)
|
||||
|
||||
|
||||
@@ -142,3 +143,15 @@ class CustomerAddressAdmin(ModelAdmin):
|
||||
def get_queryset(self, request):
|
||||
qs = super().get_queryset(request)
|
||||
return qs.filter(hidden=False)
|
||||
|
||||
|
||||
@admin.register(ProductCategory)
|
||||
class ProductCategoryAdmin(ModelAdmin):
|
||||
list_display = (
|
||||
"id",
|
||||
"name",
|
||||
"parent",
|
||||
"promoted",
|
||||
"hidden",
|
||||
"show_in_navbar",
|
||||
)
|
||||
|
||||
@@ -10,6 +10,7 @@ class ProductFilter(django_filters.FilterSet):
|
||||
field_name="name", lookup_expr="icontains", label=_("Nombre")
|
||||
)
|
||||
tags = django_filters.BaseInFilter(field_name="tags", label=_("Etiquetas"))
|
||||
category = django_filters.BaseInFilter(field_name="categories", label=_("Categorías"))
|
||||
price_lt = django_filters.NumberFilter(method="filter_price_lt")
|
||||
price_gt = django_filters.NumberFilter(method="filter_price_gt")
|
||||
o = OrderingFilter(
|
||||
@@ -42,4 +43,5 @@ class ProductFilter(django_filters.FilterSet):
|
||||
"stock",
|
||||
"is_digital_asset",
|
||||
"tags",
|
||||
"category",
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Generated by Django 5.1.3 on 2024-12-23 12:01
|
||||
# Generated by Django 5.1.3 on 2024-12-31 09:48
|
||||
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
@@ -507,12 +507,6 @@ class Migration(migrations.Migration):
|
||||
blank=True, to="files.fileupload", verbose_name="imágenes"
|
||||
),
|
||||
),
|
||||
(
|
||||
"tags",
|
||||
models.ManyToManyField(
|
||||
blank=True, to="shop.tag", verbose_name="etiquetas"
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "producto",
|
||||
@@ -646,6 +640,64 @@ class Migration(migrations.Migration):
|
||||
"verbose_name_plural": "líneas de carrito",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="ProductCategory",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("name", models.CharField(max_length=32)),
|
||||
(
|
||||
"promoted",
|
||||
models.BooleanField(default=False, verbose_name="promocionada"),
|
||||
),
|
||||
("hidden", models.BooleanField(default=False, verbose_name="oculta")),
|
||||
(
|
||||
"show_in_navbar",
|
||||
models.BooleanField(
|
||||
default=False, verbose_name="mostrar en cabecera"
|
||||
),
|
||||
),
|
||||
(
|
||||
"slug",
|
||||
models.SlugField(
|
||||
blank=True,
|
||||
default="",
|
||||
max_length=48,
|
||||
unique=True,
|
||||
verbose_name="slug",
|
||||
),
|
||||
),
|
||||
(
|
||||
"parent",
|
||||
models.ForeignKey(
|
||||
blank=True,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_NULL,
|
||||
to="shop.productcategory",
|
||||
verbose_name="categoría padre",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "categoría",
|
||||
"verbose_name_plural": "categorías",
|
||||
"ordering": ("name",),
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="categories",
|
||||
field=models.ManyToManyField(
|
||||
blank=True, to="shop.productcategory", verbose_name="categorías"
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="ProductBatch",
|
||||
fields=[
|
||||
@@ -758,6 +810,13 @@ class Migration(migrations.Migration):
|
||||
"verbose_name_plural": "métodos de envío",
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="product",
|
||||
name="tags",
|
||||
field=models.ManyToManyField(
|
||||
blank=True, to="shop.tag", verbose_name="etiquetas"
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="ProductPrice",
|
||||
fields=[
|
||||
|
||||
+25
-1
@@ -35,6 +35,27 @@ class Tag(models.Model):
|
||||
ordering = ("name",)
|
||||
|
||||
|
||||
class ProductCategory(models.Model):
|
||||
name = models.CharField(max_length=32)
|
||||
parent = models.ForeignKey('shop.ProductCategory', on_delete=models.SET_NULL, null=True, blank=True, verbose_name=_('categoría padre'))
|
||||
promoted = models.BooleanField(default=False, verbose_name=_('promocionada'))
|
||||
hidden = models.BooleanField(default=False, verbose_name=_('oculta'))
|
||||
show_in_navbar = models.BooleanField(default=False, verbose_name=_('mostrar en cabecera'))
|
||||
slug = models.SlugField(max_length=48, blank=True, default="", verbose_name=_("slug"), unique=True, db_index=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.slug = slugify(self.name)
|
||||
super().save()
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("categoría")
|
||||
verbose_name_plural = _("categorías")
|
||||
ordering = ("name",)
|
||||
|
||||
|
||||
class Product(TimestampedModel):
|
||||
sku = models.CharField(
|
||||
max_length=64,
|
||||
@@ -68,6 +89,7 @@ class Product(TimestampedModel):
|
||||
"files.FileUpload", blank=True, verbose_name=_("imágenes")
|
||||
)
|
||||
tags = models.ManyToManyField("shop.Tag", blank=True, verbose_name=_("etiquetas"))
|
||||
categories = models.ManyToManyField("shop.ProductCategory", blank=True, verbose_name=_("categorías"))
|
||||
brand = models.ForeignKey(
|
||||
"shop.Brand",
|
||||
blank=True,
|
||||
@@ -415,7 +437,9 @@ class CustomerAddress(models.Model):
|
||||
BILLING = "BILL", _("facturación")
|
||||
SHIPPING = "SHIP", _("envío")
|
||||
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, verbose_name=_("usuario"))
|
||||
user = models.ForeignKey(
|
||||
User, on_delete=models.CASCADE, null=True, verbose_name=_("usuario")
|
||||
)
|
||||
vat_id = models.CharField(
|
||||
max_length=16,
|
||||
blank=True,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
from decimal import Decimal
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from config.tests.mixins import TestUserAuthenticationMixin
|
||||
from shop.models import Product, ProductPrice, Tax, CustomerAddress
|
||||
from shop.models import CustomerAddress, Product, ProductPrice, Tax
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ from decimal import Decimal
|
||||
from django.contrib.auth import get_user_model
|
||||
from rest_framework.test import APITestCase as TestCase
|
||||
|
||||
from shop.models import Product, ProductPrice, Tax, CustomerAddress
|
||||
from shop.models import CustomerAddress, Product, ProductPrice, Tax
|
||||
from shop.utils import create_order, create_order_line_for_product
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
+5
-4
@@ -1,16 +1,17 @@
|
||||
from decimal import Decimal
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
from shop.models import (
|
||||
Cart,
|
||||
CustomerAddress,
|
||||
Order,
|
||||
OrderLine,
|
||||
Product,
|
||||
ProductBatch,
|
||||
Cart,
|
||||
CustomerAddress,
|
||||
ShippingMethod,
|
||||
ProductPrice,
|
||||
ShippingMethod,
|
||||
)
|
||||
from django.contrib.auth import get_user_model
|
||||
|
||||
User = get_user_model()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user