reworked product initial logic
rodzic
fb5976282b
commit
0938a66022
|
@ -10,38 +10,42 @@ from wagtail.admin.forms.models import WagtailAdminModelForm
|
|||
from store import models
|
||||
|
||||
|
||||
class ProductConfigAdmin(ModelAdmin):
|
||||
model = models.ProductConfig
|
||||
list_display = ("author__name", "color", "price")
|
||||
search_fields = ("author__name", "color", "price")
|
||||
class ProductAuthorAdmin(ModelAdmin):
|
||||
model = models.ProductAuthor
|
||||
list_display = ("name", )
|
||||
|
||||
|
||||
class ProductCategoryAdmin(ModelAdmin):
|
||||
model = models.ProductCategory
|
||||
list_display = ("name", )
|
||||
|
||||
|
||||
class ProductCategoryParamAdmin(ModelAdmin):
|
||||
model = models.ProductCategoryParam
|
||||
list_display = ("key", "param_type")
|
||||
|
||||
|
||||
class ProductTemplateAdmin(ModelAdmin):
|
||||
model = models.ProductTemplate
|
||||
list_display = ("title", )
|
||||
|
||||
|
||||
class ProductAdminForm(WagtailAdminModelForm):
|
||||
|
||||
template_title = fields.CharField()
|
||||
template_code = fields.CharField()
|
||||
template_description = fields.CharField()
|
||||
|
||||
class Meta:
|
||||
fields = ("template_title", "template_code", "template_description")
|
||||
model = models.Product
|
||||
list_display = ("title", "code")
|
||||
|
||||
|
||||
class ProductAdmin(ModelAdmin):
|
||||
model = models.Product
|
||||
form = ProductAdminForm
|
||||
list_display = ("title", "price")
|
||||
|
||||
|
||||
class StoreAdminGroup(ModelAdminGroup):
|
||||
menu_label = "Store"
|
||||
menu_icon = 'folder-open-inverse'
|
||||
menu_order = 200
|
||||
items = (ProductConfigAdmin, ProductTemplateAdmin, ProductAdmin)
|
||||
|
||||
items = (
|
||||
ProductAuthorAdmin,
|
||||
ProductCategoryAdmin,
|
||||
ProductCategoryParamAdmin,
|
||||
ProductTemplateAdmin,
|
||||
ProductAdmin
|
||||
)
|
||||
|
||||
|
||||
modeladmin_register(StoreAdminGroup)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# Generated by Django 4.1.8 on 2023-04-25 22:22
|
||||
# Generated by Django 4.1.9 on 2023-05-10 19:40
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import modelcluster.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -12,6 +13,16 @@ class Migration(migrations.Migration):
|
|||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Product',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('price', models.FloatField()),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProductAuthor',
|
||||
fields=[
|
||||
|
@ -19,6 +30,37 @@ class Migration(migrations.Migration):
|
|||
('name', models.CharField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProductCategory',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=255)),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProductCategoryParam',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('key', models.CharField(max_length=200)),
|
||||
('param_type', models.CharField(choices=[('int', 'Int'), ('str', 'String'), ('float', 'Float')], max_length=200)),
|
||||
('category', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='category_params', to='store.productcategory')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TemplateParamValue',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('value', models.CharField(max_length=255)),
|
||||
('param', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.productcategoryparam')),
|
||||
('product', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='param_values', to='store.product')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProductTemplate',
|
||||
fields=[
|
||||
|
@ -26,32 +68,24 @@ class Migration(migrations.Migration):
|
|||
('title', models.CharField(max_length=255)),
|
||||
('code', models.CharField(max_length=255)),
|
||||
('description', models.TextField()),
|
||||
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.productauthor')),
|
||||
('category', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.productcategory')),
|
||||
],
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProductImage',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('image', models.ImageField(upload_to='')),
|
||||
('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='store.producttemplate')),
|
||||
('template', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='images', to='store.producttemplate')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ProductConfig',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('color', models.CharField(max_length=255)),
|
||||
('size', models.CharField(max_length=50)),
|
||||
('price', models.FloatField()),
|
||||
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.productauthor')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Product',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('config', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.productconfig')),
|
||||
('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.producttemplate')),
|
||||
],
|
||||
migrations.AddField(
|
||||
model_name='product',
|
||||
name='template',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='store.producttemplate'),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,33 +1,94 @@
|
|||
from django.db import models
|
||||
|
||||
from modelcluster.models import ClusterableModel
|
||||
from modelcluster.fields import ParentalKey
|
||||
from wagtail.admin.panels import (
|
||||
FieldPanel,
|
||||
InlinePanel
|
||||
)
|
||||
from wagtail.models import Orderable
|
||||
|
||||
|
||||
class ProductAuthor(models.Model):
|
||||
name = models.CharField(max_length=255)
|
||||
# TODO - author contact info? maybe foreignkey with user
|
||||
|
||||
class ProductTemplate(models.Model):
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class ProductCategory(ClusterableModel):
|
||||
name = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
panels = [
|
||||
FieldPanel("name"),
|
||||
InlinePanel("category_params")
|
||||
]
|
||||
|
||||
|
||||
class CategoryParamTypeChoices(models.TextChoices):
|
||||
INT = "int"
|
||||
STRING = "str"
|
||||
FLOAT = "float"
|
||||
|
||||
|
||||
class ProductCategoryParam(ClusterableModel):
|
||||
category = ParentalKey(ProductCategory, on_delete=models.CASCADE, related_name="category_params")
|
||||
key = models.CharField(max_length=200)
|
||||
param_type = models.CharField(max_length=200, choices=CategoryParamTypeChoices.choices)
|
||||
|
||||
def __str__(self):
|
||||
return self.key
|
||||
|
||||
|
||||
class ProductTemplate(ClusterableModel):
|
||||
category = models.ForeignKey(ProductCategory, on_delete=models.CASCADE)
|
||||
author = models.ForeignKey(ProductAuthor, on_delete=models.CASCADE)
|
||||
title = models.CharField(max_length=255)
|
||||
code = models.CharField(max_length=255)
|
||||
description = models.TextField()
|
||||
|
||||
def __str__(self):
|
||||
return self.title
|
||||
|
||||
def get_images(self):
|
||||
return self.images.objects.all().values_list("image")
|
||||
|
||||
panels = [
|
||||
FieldPanel("category"),
|
||||
FieldPanel("author"),
|
||||
FieldPanel('title'),
|
||||
FieldPanel('code'),
|
||||
FieldPanel('description'),
|
||||
InlinePanel("images")
|
||||
]
|
||||
|
||||
|
||||
class ProductImage(models.Model):
|
||||
template = models.ForeignKey(
|
||||
template = ParentalKey(
|
||||
ProductTemplate, on_delete=models.CASCADE, related_name="images"
|
||||
)
|
||||
image = models.ImageField()
|
||||
|
||||
|
||||
class ProductConfig(models.Model):
|
||||
author = models.ForeignKey(ProductAuthor, on_delete=models.CASCADE)
|
||||
color = models.CharField(max_length=255)
|
||||
size = models.CharField(max_length=50)
|
||||
class Product(ClusterableModel):
|
||||
template = models.ForeignKey(ProductTemplate, on_delete=models.CASCADE)
|
||||
price = models.FloatField()
|
||||
|
||||
panels = [
|
||||
FieldPanel("template"),
|
||||
FieldPanel("price"),
|
||||
InlinePanel("param_values")
|
||||
]
|
||||
|
||||
class Product(models.Model):
|
||||
template = models.ForeignKey(ProductTemplate, on_delete=models.CASCADE)
|
||||
config = models.ForeignKey(ProductConfig, on_delete=models.CASCADE)
|
||||
@property
|
||||
def title(self):
|
||||
return f"{self.template.title} - {self.price}"
|
||||
|
||||
|
||||
class TemplateParamValue(models.Model):
|
||||
param = models.ForeignKey(ProductCategoryParam, on_delete=models.CASCADE)
|
||||
product = ParentalKey(Product, on_delete=models.CASCADE, related_name="param_values")
|
||||
value = models.CharField(max_length=255)
|
||||
|
|
Ładowanie…
Reference in New Issue