+ migration of categories/subcategories

This commit is contained in:
Phil Zhitnikov 2023-08-21 16:22:03 +04:00
parent 60ff4bb6b0
commit 1445c87c0a
4 changed files with 148 additions and 86 deletions

View File

@ -122,20 +122,22 @@ payment_methods = {
}
def create_categories():
for cat_name, subcat_names in tqdm(category_names.items(), desc="Creating categories"):
category, _ = Category.objects.get_or_create(name=cat_name, parent=None)
for subcat_name in subcat_names:
Category.objects.get_or_create(name=subcat_name, parent_id=category.id)
def create_payment_types():
for slug, data in tqdm(payment_methods.items(), desc="Creating payment methods"):
PaymentMethod.objects.get_or_create(slug=slug, defaults=data)
class Command(BaseCommand):
help = ''' Create root categories '''
def create_categories(self):
for cat_name, subcat_names in tqdm(category_names.items(), desc="Creating categories"):
category, _ = Category.objects.get_or_create(name=cat_name, parent=None)
for subcat_name in subcat_names:
Category.objects.get_or_create(name=subcat_name, parent_id=category.id)
def create_payment_types(self):
for slug, data in tqdm(payment_methods.items(), desc="Creating payment methods"):
PaymentMethod.objects.get_or_create(slug=slug, defaults=data)
def handle(self, *args, **kwargs):
self.create_categories()
self.create_payment_types()
create_categories()
create_payment_types()

View File

@ -0,0 +1,134 @@
# Generated by Django 4.2.2 on 2023-08-19 16:45
import datetime
import django.core.validators
from django.conf import settings
from django.db import migrations, models, transaction
import django.db.models.deletion
import mptt.fields
from mptt import register, managers
from store.management.commands.create_initial_data import create_categories
def create_initial_categories(apps, schema_editor):
create_categories()
# Dummy model with the removed field(s)
class OldChecklist(models.Model):
id = models.CharField(primary_key=True, max_length=settings.CHECKLIST_ID_LENGTH)
category_id = models.PositiveIntegerField()
subcategory = models.CharField('Подкатегория', max_length=20, blank=True, null=True)
class Meta:
managed = False
db_table = 'store_checklist'
# Add mptt fields to Category
# Loop through orders, save subcategory names and category ids
# Create subcategories, link to parent category
# Loop through orders, if subcategory was present, set it as category
# Perform migration - remove subcategory field
def create_subcategories(apps, schema_editor):
Checklist = apps.get_model("store", "Checklist")
Category = apps.get_model("store", "Category")
# Loop through orders, save subcategory names and category ids
# Create subcategories, link to parent category
# If Checklist had subcategory, set it as category
with transaction.atomic():
for checklist in OldChecklist.objects.all():
if checklist.subcategory is None or checklist.category_id is None:
continue
category_data = {'name': checklist.subcategory, 'parent_id': checklist.category_id}
# just to overcome not-null constraint errors for mptt
mptt_data = {'level': 0, 'lft': 0, 'rght': 0, 'tree_id': 0}
subcat_obj, _ = Category.objects.get_or_create(**category_data, defaults=mptt_data)
# To really update the Checklist, we must use a real model instead of the dummy OldChecklist one
Checklist.objects.filter(id=checklist.id).update(category_id=subcat_obj.id)
def rebuild_tree(apps, schema_editor):
model = apps.get_model('store', 'Category')
manager = managers.TreeManager()
manager.model = model
register(model)
manager.contribute_to_class(model, 'objects')
manager.rebuild()
class Migration(migrations.Migration):
dependencies = [
('store', '0040_alter_paymentmethod_cardnumber_and_more'),
]
operations = [
migrations.RemoveField(
model_name='category',
name='slug',
),
migrations.AddField(
model_name='category',
name='commission',
field=models.DecimalField(decimal_places=2, default=0, max_digits=10, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)], verbose_name='Дополнительная комиссия, %'),
),
migrations.AddField(
model_name='category',
name='level',
field=models.PositiveIntegerField(default=0, editable=False),
preserve_default=False,
),
migrations.AddField(
model_name='category',
name='lft',
field=models.PositiveIntegerField(default=0, editable=False),
preserve_default=False,
),
migrations.AddField(
model_name='category',
name='parent',
field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='store.category', verbose_name='Родительская категория'),
),
migrations.AddField(
model_name='category',
name='rght',
field=models.PositiveIntegerField(default=0, editable=False),
preserve_default=False,
),
migrations.AddField(
model_name='category',
name='tree_id',
field=models.PositiveIntegerField(db_index=True, default=0, editable=False),
preserve_default=False,
),
migrations.RunPython(code=create_initial_categories),
migrations.RunPython(code=create_subcategories),
migrations.RunPython(code=rebuild_tree),
migrations.AddField(
model_name='globalsettings',
name='time_to_buy',
field=models.DurationField(default=datetime.timedelta(seconds=10800), help_text="Через N времени заказ переходит из статуса 'Новый' в 'Черновик'", verbose_name='Время на покупку'),
),
migrations.AlterField(
model_name='promocode',
name='discount',
field=models.PositiveIntegerField(verbose_name='Скидка в рублях'),
),
migrations.RemoveField(
model_name='checklist',
name='subcategory',
),
]

View File

@ -1,35 +0,0 @@
# Generated by Django 4.2.2 on 2023-08-17 23:19
import datetime
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('store', '0040_alter_paymentmethod_cardnumber_and_more'),
]
operations = [
migrations.RemoveField(
model_name='checklist',
name='category',
),
migrations.RemoveField(
model_name='checklist',
name='subcategory',
),
migrations.AddField(
model_name='globalsettings',
name='time_to_buy',
field=models.DurationField(default=datetime.timedelta(seconds=10800), help_text="Через N времени заказ переходит из статуса 'Новый' в 'Черновик'", verbose_name='Время на покупку'),
),
migrations.AlterField(
model_name='promocode',
name='discount',
field=models.PositiveIntegerField(verbose_name='Скидка в рублях'),
),
migrations.DeleteModel(
name='Category',
),
]

View File

@ -1,39 +0,0 @@
# Generated by Django 4.2.2 on 2023-08-17 23:20
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
import mptt.fields
class Migration(migrations.Migration):
dependencies = [
('store', '0041_remove_checklist_category_and_more'),
]
operations = [
migrations.CreateModel(
name='Category',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=20, verbose_name='Название')),
('delivery_price_CN_RU', models.DecimalField(decimal_places=2, default=0, max_digits=10, verbose_name='Цена доставки Китай-РФ')),
('commission', models.DecimalField(decimal_places=2, default=0, max_digits=10, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)], verbose_name='Дополнительная комиссия, %')),
('lft', models.PositiveIntegerField(editable=False)),
('rght', models.PositiveIntegerField(editable=False)),
('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
('level', models.PositiveIntegerField(editable=False)),
('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='children', to='store.category', verbose_name='Родительская категория')),
],
options={
'verbose_name': 'Категория',
'verbose_name_plural': 'Категории',
},
),
migrations.AddField(
model_name='checklist',
name='category',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='store.category', verbose_name='Категория'),
),
]