From 091a00949b890d46eac1b74a897b9abc760426a1 Mon Sep 17 00:00:00 2001 From: qasim Date: Wed, 3 Sep 2025 01:50:01 +0500 Subject: [PATCH 1/8] fix: upgrade oscar django --- apps/catalogue/apps.py | 4 +- apps/catalogue/migrations/0001_initial.py | 31 ++--- .../migrations/0002_auto_20150217_1221.py | 2 +- .../migrations/0003_data_migration_slugs.py | 3 +- .../migrations/0005_auto_20150604_1450.py | 2 +- .../migrations/0006_auto_20150807_1725.py | 2 +- .../migrations/0007_auto_20151207_1440.py | 2 +- .../migrations/0008_auto_20160304_1652.py | 2 +- .../migrations/0009_slugfield_noop.py | 2 +- .../migrations/0010_auto_20170420_0439.py | 2 +- .../migrations/0013_auto_20170821_1548.py | 2 +- .../migrations/0017_auto_20190816_0938.py | 29 +++++ .../migrations/0017_auto_20210225_1829.py | 18 --- .../migrations/0018_auto_20191220_0920.py | 28 +++++ .../migrations/0018_auto_20240113_2047.py | 119 ------------------ .../migrations/0019_auto_20240807_1624.py | 34 ----- .../migrations/0019_option_required.py | 37 ++++++ .../migrations/0020_auto_20200801_0817.py | 27 ++++ .../migrations/0021_auto_20201005_0844.py | 33 +++++ .../migrations/0022_auto_20210210_0539.py | 18 +++ .../migrations/0023_auto_20210824_1414.py | 19 +++ .../0024_remove_duplicate_attributes.py | 106 ++++++++++++++++ ...ttribute_code_uniquetogether_constraint.py | 17 +++ .../0026_predefined_product_options.py | 38 ++++++ ...code_attributeoptiongroup_code_and_more.py | 41 ++++++ .../migrations/0028_product_priority.py | 25 ++++ .../catalogue/migrations/0029_product_code.py | 23 ++++ apps/communication/migrations/0001_initial.py | 5 +- ...tification_category_make_code_uppercase.py | 2 +- apps/customer/migrations/0001_initial.py | 2 +- .../migrations/0002_auto_20150807_1725.py | 4 +- apps/customer/migrations/0004_email_save.py | 2 +- apps/dashboard/apps.py | 50 ++++---- .../banners/migrations/0001_initial.py | 5 +- apps/dashboard/banners/tables.py | 3 +- .../banners/templatetags/banner_tags.py | 3 +- apps/dashboard/configurable_menu/apps.py | 2 +- .../migrations/0001_initial.py | 2 +- ...partnerconfigurablemenuitem_patner_menu.py | 2 +- .../0003_partnerconfigurablemenu_partner.py | 2 +- .../0008_partnerconfigurablemenuitem_code.py | 2 +- apps/dashboard/configurable_menu/tables.py | 6 +- apps/dashboard/dashboard_payment/apps.py | 69 +++++----- apps/dashboard/settings/apps.py | 3 +- apps/dashboard/settings/context_processors.py | 2 - .../settings/migrations/0001_initial.py | 3 +- .../migrations/0004_auto_20200529_2031.py | 3 +- .../migrations/0006_auto_20210202_1402.py | 2 +- apps/dashboard/settings/tests.py | 2 - apps/dashboard/settings/views.py | 2 - apps/partner/migrations/0001_initial.py | 4 +- .../migrations/0002_auto_20141007_2032.py | 2 +- .../migrations/0003_auto_20150604_1450.py | 2 +- .../migrations/0004_auto_20160107_1755.py | 2 +- apps/payment/migrations/0001_initial.py | 5 +- .../migrations/0002_auto_20141007_2032.py | 2 +- apps/payment/migrations/0005_paymentmethod.py | 2 +- .../0006_paymentmethod_price_currency.py | 2 +- apps/shipping/migrations/0001_initial.py | 5 +- .../migrations/0003_auto_20181115_1953.py | 1 + docker-compose.yml | 4 +- e_store_primzel/settings/install_apps.py | 54 ++++---- e_store_primzel/settings/navigation.py | 2 +- e_store_primzel/settings/payment.py | 2 +- requirements | 4 +- 65 files changed, 612 insertions(+), 325 deletions(-) create mode 100644 apps/catalogue/migrations/0017_auto_20190816_0938.py delete mode 100644 apps/catalogue/migrations/0017_auto_20210225_1829.py create mode 100644 apps/catalogue/migrations/0018_auto_20191220_0920.py delete mode 100644 apps/catalogue/migrations/0018_auto_20240113_2047.py delete mode 100644 apps/catalogue/migrations/0019_auto_20240807_1624.py create mode 100644 apps/catalogue/migrations/0019_option_required.py create mode 100644 apps/catalogue/migrations/0020_auto_20200801_0817.py create mode 100644 apps/catalogue/migrations/0021_auto_20201005_0844.py create mode 100644 apps/catalogue/migrations/0022_auto_20210210_0539.py create mode 100644 apps/catalogue/migrations/0023_auto_20210824_1414.py create mode 100644 apps/catalogue/migrations/0024_remove_duplicate_attributes.py create mode 100644 apps/catalogue/migrations/0025_attribute_code_uniquetogether_constraint.py create mode 100644 apps/catalogue/migrations/0026_predefined_product_options.py create mode 100644 apps/catalogue/migrations/0027_attributeoption_code_attributeoptiongroup_code_and_more.py create mode 100644 apps/catalogue/migrations/0028_product_priority.py create mode 100644 apps/catalogue/migrations/0029_product_code.py diff --git a/apps/catalogue/apps.py b/apps/catalogue/apps.py index 654367b..705d3de 100644 --- a/apps/catalogue/apps.py +++ b/apps/catalogue/apps.py @@ -1,5 +1,5 @@ import oscar.apps.catalogue.apps as apps -from django.conf.urls import url +from django.urls import path from oscar.core.loading import get_class @@ -12,7 +12,7 @@ def ready(self): def get_urls(self): urls = [ - url(r'^(?P[\w-]*)_(?P\d+)/quick$', + path('(?P[\w-]*)_(?P\d+)/quick', self.quick_detail_view.as_view(template_name='oscar/catalogue/partials/product_quick_view.html', enforce_paths=False), name='quick_detail') ] diff --git a/apps/catalogue/migrations/0001_initial.py b/apps/catalogue/migrations/0001_initial.py index 74dad3e..fd1e64d 100644 --- a/apps/catalogue/migrations/0001_initial.py +++ b/apps/catalogue/migrations/0001_initial.py @@ -1,11 +1,14 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations -import oscar.models.fields.autoslugfield -import django.db.models.deletion import django.core.validators import oscar.models.fields +import oscar.models.fields.autoslugfield +from django.conf import settings +from django.db import models, migrations +from django.utils.module_loading import import_string + +models_AutoField = import_string(settings.DEFAULT_AUTO_FIELD) class Migration(migrations.Migration): @@ -18,7 +21,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='AttributeOption', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('option', models.CharField(max_length=255, verbose_name='Option')), ], options={ @@ -31,7 +34,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='AttributeOptionGroup', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=128, verbose_name='Name')), ], options={ @@ -44,7 +47,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Category', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('path', models.CharField(unique=True, max_length=255)), ('depth', models.PositiveIntegerField()), ('numchild', models.PositiveIntegerField(default=0)), @@ -65,7 +68,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Option', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=128, verbose_name='Name')), ('code', oscar.models.fields.autoslugfield.AutoSlugField(populate_from='name', unique=True, verbose_name='Code', max_length=128, editable=False, blank=True)), ('type', models.CharField(default='Required', max_length=128, verbose_name='Status', choices=[('Required', 'Required - a value for this option must be specified'), ('Optional', 'Optional - a value for this option can be omitted')])), @@ -80,7 +83,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Product', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('structure', models.CharField(default='standalone', max_length=10, verbose_name='Product structure', choices=[('standalone', 'Stand-alone product'), ('parent', 'Parent product'), ('child', 'Child product')])), ('upc', oscar.models.fields.NullCharField(unique=True, verbose_name='UPC', max_length=64, help_text='Universal Product Code (UPC) is an identifier for a product which is not specific to a particular supplier. Eg an ISBN for a book.')), ('title', models.CharField(max_length=255, verbose_name='Title', blank=True)), @@ -102,7 +105,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ProductAttribute', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=128, verbose_name='Name')), ('code', models.SlugField(max_length=128, verbose_name='Code', validators=[django.core.validators.RegexValidator(regex='^[a-zA-Z\\-_][0-9a-zA-Z\\-_]*$', message="Code can only contain the letters a-z, A-Z, digits, minus and underscores, and can't start with a digit")])), ('type', models.CharField(default='text', max_length=20, verbose_name='Type', choices=[('text', 'Text'), ('integer', 'Integer'), ('boolean', 'True / False'), ('float', 'Float'), ('richtext', 'Rich Text'), ('date', 'Date'), ('option', 'Option'), ('entity', 'Entity'), ('file', 'File'), ('image', 'Image')])), @@ -120,7 +123,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ProductAttributeValue', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('value_text', models.TextField(blank=True, verbose_name='Text', null=True)), ('value_integer', models.IntegerField(blank=True, verbose_name='Integer', null=True)), ('value_boolean', models.NullBooleanField(verbose_name='Boolean')), @@ -145,7 +148,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ProductCategory', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('category', models.ForeignKey(verbose_name='Category', to='catalogue.Category', on_delete=models.CASCADE)), ('product', models.ForeignKey(verbose_name='Product', to='catalogue.Product', on_delete=models.CASCADE)), ], @@ -160,7 +163,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ProductClass', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=128, verbose_name='Name')), ('slug', oscar.models.fields.autoslugfield.AutoSlugField(populate_from='name', unique=True, verbose_name='Slug', max_length=128, editable=False, blank=True)), ('requires_shipping', models.BooleanField(default=True, verbose_name='Requires shipping?')), @@ -178,7 +181,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ProductImage', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('original', models.ImageField(upload_to='images/products/%Y/%m/', max_length=255, verbose_name='Original')), ('caption', models.CharField(max_length=200, verbose_name='Caption', blank=True)), ('display_order', models.PositiveIntegerField(default=0, verbose_name='Display order', help_text='An image with a display order of zero will be the primary image for a product')), @@ -196,7 +199,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ProductRecommendation', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models_AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('ranking', models.PositiveSmallIntegerField(default=0, verbose_name='Ranking', help_text='Determines order of the products. A product with a higher value will appear before one with a lower ranking.')), ('primary', models.ForeignKey(verbose_name='Primary product', related_name='primary_recommendations', to='catalogue.Product', on_delete=models.CASCADE)), ('recommendation', models.ForeignKey(verbose_name='Recommended product', to='catalogue.Product', on_delete=models.CASCADE)), diff --git a/apps/catalogue/migrations/0002_auto_20150217_1221.py b/apps/catalogue/migrations/0002_auto_20150217_1221.py index 9dd2b5e..d362707 100644 --- a/apps/catalogue/migrations/0002_auto_20150217_1221.py +++ b/apps/catalogue/migrations/0002_auto_20150217_1221.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations +from django.db import migrations class Migration(migrations.Migration): diff --git a/apps/catalogue/migrations/0003_data_migration_slugs.py b/apps/catalogue/migrations/0003_data_migration_slugs.py index 90267e3..075ea68 100644 --- a/apps/catalogue/migrations/0003_data_migration_slugs.py +++ b/apps/catalogue/migrations/0003_data_migration_slugs.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations - +from django.db import migrations from oscar.core.loading import get_model # Django database migrations require us to fetch the category model diff --git a/apps/catalogue/migrations/0005_auto_20150604_1450.py b/apps/catalogue/migrations/0005_auto_20150604_1450.py index beda87a..7708a9c 100644 --- a/apps/catalogue/migrations/0005_auto_20150604_1450.py +++ b/apps/catalogue/migrations/0005_auto_20150604_1450.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations import django.db.models.deletion +from django.db import models, migrations class Migration(migrations.Migration): diff --git a/apps/catalogue/migrations/0006_auto_20150807_1725.py b/apps/catalogue/migrations/0006_auto_20150807_1725.py index d83193b..0944b69 100644 --- a/apps/catalogue/migrations/0006_auto_20150807_1725.py +++ b/apps/catalogue/migrations/0006_auto_20150807_1725.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations import django.core.validators import oscar.core.validators +from django.db import models, migrations class Migration(migrations.Migration): diff --git a/apps/catalogue/migrations/0007_auto_20151207_1440.py b/apps/catalogue/migrations/0007_auto_20151207_1440.py index 5d38430..2755e38 100644 --- a/apps/catalogue/migrations/0007_auto_20151207_1440.py +++ b/apps/catalogue/migrations/0007_auto_20151207_1440.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import migrations, models +from django.db import migrations class Migration(migrations.Migration): diff --git a/apps/catalogue/migrations/0008_auto_20160304_1652.py b/apps/catalogue/migrations/0008_auto_20160304_1652.py index 51824a9..701f8b9 100644 --- a/apps/catalogue/migrations/0008_auto_20160304_1652.py +++ b/apps/catalogue/migrations/0008_auto_20160304_1652.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import migrations, models import django.core.validators import oscar.core.validators +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/apps/catalogue/migrations/0009_slugfield_noop.py b/apps/catalogue/migrations/0009_slugfield_noop.py index 07e74a1..9dcd20c 100644 --- a/apps/catalogue/migrations/0009_slugfield_noop.py +++ b/apps/catalogue/migrations/0009_slugfield_noop.py @@ -2,8 +2,8 @@ # Generated by Django 1.9.7 on 2016-07-13 08:44 from __future__ import unicode_literals -from django.db import migrations import oscar.models.fields.slugfield +from django.db import migrations class Migration(migrations.Migration): diff --git a/apps/catalogue/migrations/0010_auto_20170420_0439.py b/apps/catalogue/migrations/0010_auto_20170420_0439.py index b2941c6..6aa4c14 100644 --- a/apps/catalogue/migrations/0010_auto_20170420_0439.py +++ b/apps/catalogue/migrations/0010_auto_20170420_0439.py @@ -2,8 +2,8 @@ # Generated by Django 1.11 on 2017-04-20 05:51 from __future__ import unicode_literals -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/apps/catalogue/migrations/0013_auto_20170821_1548.py b/apps/catalogue/migrations/0013_auto_20170821_1548.py index 1e64a2c..0c764c1 100644 --- a/apps/catalogue/migrations/0013_auto_20170821_1548.py +++ b/apps/catalogue/migrations/0013_auto_20170821_1548.py @@ -2,8 +2,8 @@ # Generated by Django 1.11.4 on 2017-08-21 14:48 from __future__ import unicode_literals -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/apps/catalogue/migrations/0017_auto_20190816_0938.py b/apps/catalogue/migrations/0017_auto_20190816_0938.py new file mode 100644 index 0000000..553bccb --- /dev/null +++ b/apps/catalogue/migrations/0017_auto_20190816_0938.py @@ -0,0 +1,29 @@ +# Generated by Django 2.2.4 on 2019-08-16 08:38 + +import oscar.utils.models +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0016_auto_20190327_0757'), + ] + + operations = [ + migrations.AlterField( + model_name='productattributevalue', + name='value_file', + field=models.FileField(blank=True, max_length=255, null=True, upload_to=oscar.utils.models.get_image_upload_path), + ), + migrations.AlterField( + model_name='productattributevalue', + name='value_image', + field=models.ImageField(blank=True, max_length=255, null=True, upload_to=oscar.utils.models.get_image_upload_path), + ), + migrations.AlterField( + model_name='productimage', + name='original', + field=models.ImageField(max_length=255, upload_to=oscar.utils.models.get_image_upload_path, verbose_name='Original'), + ), + ] diff --git a/apps/catalogue/migrations/0017_auto_20210225_1829.py b/apps/catalogue/migrations/0017_auto_20210225_1829.py deleted file mode 100644 index 4c87007..0000000 --- a/apps/catalogue/migrations/0017_auto_20210225_1829.py +++ /dev/null @@ -1,18 +0,0 @@ -# Generated by Django 2.2.5 on 2021-02-25 18:29 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('catalogue', '0016_auto_20190327_0757'), - ] - - operations = [ - migrations.AlterField( - model_name='category', - name='depth', - field=models.PositiveIntegerField(default=1), - ), - ] diff --git a/apps/catalogue/migrations/0018_auto_20191220_0920.py b/apps/catalogue/migrations/0018_auto_20191220_0920.py new file mode 100644 index 0000000..dcf6627 --- /dev/null +++ b/apps/catalogue/migrations/0018_auto_20191220_0920.py @@ -0,0 +1,28 @@ +# Generated by Django 2.2.9 on 2019-12-20 09:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0017_auto_20190816_0938'), + ] + + operations = [ + migrations.AddField( + model_name='category', + name='ancestors_are_public', + field=models.BooleanField(db_index=True, default=True, help_text='The ancestors of this category are public', verbose_name='Ancestor categories are public'), + ), + migrations.AddField( + model_name='category', + name='is_public', + field=models.BooleanField(db_index=True, default=True, help_text='Show this category in search results and catalogue listings.', verbose_name='Is public'), + ), + migrations.AlterField( + model_name='product', + name='is_public', + field=models.BooleanField(db_index=True, default=True, help_text='Show this product in search results and catalogue listings.', verbose_name='Is public'), + ), + ] diff --git a/apps/catalogue/migrations/0018_auto_20240113_2047.py b/apps/catalogue/migrations/0018_auto_20240113_2047.py deleted file mode 100644 index 3fbf272..0000000 --- a/apps/catalogue/migrations/0018_auto_20240113_2047.py +++ /dev/null @@ -1,119 +0,0 @@ -# Generated by Django 3.2.23 on 2024-01-13 20:47 - -from django.db import migrations, models -import django.db.models.deletion -import oscar.models.fields.slugfield -import oscar.utils.models - - -class Migration(migrations.Migration): - - dependencies = [ - ('catalogue', '0017_auto_20210225_1829'), - ] - - operations = [ - migrations.AlterModelOptions( - name='option', - options={'ordering': ['order', 'name'], 'verbose_name': 'Option', 'verbose_name_plural': 'Options'}, - ), - migrations.AddField( - model_name='category', - name='ancestors_are_public', - field=models.BooleanField(db_index=True, default=True, help_text='The ancestors of this category are public', verbose_name='Ancestor categories are public'), - ), - migrations.AddField( - model_name='category', - name='is_public', - field=models.BooleanField(db_index=True, default=True, help_text='Show this category in search results and catalogue listings.', verbose_name='Is public'), - ), - migrations.AddField( - model_name='category', - name='meta_description', - field=models.TextField(blank=True, null=True, verbose_name='Meta description'), - ), - migrations.AddField( - model_name='category', - name='meta_title', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Meta title'), - ), - migrations.AddField( - model_name='option', - name='help_text', - field=models.CharField(blank=True, help_text='Help text shown to the user on the add to basket form', max_length=255, null=True, verbose_name='Help text'), - ), - migrations.AddField( - model_name='option', - name='option_group', - field=models.ForeignKey(blank=True, help_text='Select an option group if using type "Option" or "Multi Option"', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='product_options', to='catalogue.attributeoptiongroup', verbose_name='Option Group'), - ), - migrations.AddField( - model_name='option', - name='order', - field=models.IntegerField(blank=True, db_index=True, help_text='Controls the ordering of product options on product detail pages', null=True, verbose_name='Ordering'), - ), - migrations.AddField( - model_name='option', - name='required', - field=models.BooleanField(default=False, verbose_name='Is this option required?'), - ), - migrations.AddField( - model_name='product', - name='meta_description', - field=models.TextField(blank=True, null=True, verbose_name='Meta description'), - ), - migrations.AddField( - model_name='product', - name='meta_title', - field=models.CharField(blank=True, max_length=255, null=True, verbose_name='Meta title'), - ), - migrations.AlterField( - model_name='category', - name='depth', - field=models.PositiveIntegerField(), - ), - migrations.AlterField( - model_name='option', - name='name', - field=models.CharField(db_index=True, max_length=128, verbose_name='Name'), - ), - migrations.AlterField( - model_name='option', - name='type', - field=models.CharField(choices=[('text', 'Text'), ('integer', 'Integer'), ('boolean', 'True / False'), ('float', 'Float'), ('date', 'Date'), ('select', 'Select'), ('radio', 'Radio'), ('multi_select', 'Multi select'), ('checkbox', 'Checkbox')], default='text', max_length=255, verbose_name='Type'), - ), - migrations.AlterField( - model_name='product', - name='is_public', - field=models.BooleanField(db_index=True, default=True, help_text='Show this product in search results and catalogue listings.', verbose_name='Is public'), - ), - migrations.AlterField( - model_name='product', - name='slug', - field=oscar.models.fields.slugfield.SlugField(max_length=255, verbose_name='Slug'), - ), - migrations.AlterField( - model_name='productattributevalue', - name='value_boolean', - field=models.BooleanField(blank=True, db_index=True, null=True, verbose_name='Boolean'), - ), - migrations.AlterField( - model_name='productattributevalue', - name='value_file', - field=models.FileField(blank=True, max_length=255, null=True, upload_to=oscar.utils.models.get_image_upload_path), - ), - migrations.AlterField( - model_name='productattributevalue', - name='value_image', - field=models.ImageField(blank=True, max_length=255, null=True, upload_to=oscar.utils.models.get_image_upload_path), - ), - migrations.AlterField( - model_name='productimage', - name='original', - field=models.ImageField(max_length=255, upload_to=oscar.utils.models.get_image_upload_path, verbose_name='Original'), - ), - migrations.AlterUniqueTogether( - name='productattribute', - unique_together={('code', 'product_class')}, - ), - ] diff --git a/apps/catalogue/migrations/0019_auto_20240807_1624.py b/apps/catalogue/migrations/0019_auto_20240807_1624.py deleted file mode 100644 index a9a4482..0000000 --- a/apps/catalogue/migrations/0019_auto_20240807_1624.py +++ /dev/null @@ -1,34 +0,0 @@ -# Generated by Django 3.2.25 on 2024-08-07 16:24 - -from django.db import migrations -import oscar.models.fields - - -class Migration(migrations.Migration): - - dependencies = [ - ('catalogue', '0018_auto_20240113_2047'), - ] - - operations = [ - migrations.AddField( - model_name='attributeoption', - name='code', - field=oscar.models.fields.NullCharField(max_length=255, unique=True, verbose_name='Unique identifier'), - ), - migrations.AddField( - model_name='attributeoptiongroup', - name='code', - field=oscar.models.fields.NullCharField(max_length=255, unique=True, verbose_name='Unique identifier'), - ), - migrations.AddField( - model_name='category', - name='code', - field=oscar.models.fields.NullCharField(max_length=255, unique=True, verbose_name='Code'), - ), - migrations.AddField( - model_name='productimage', - name='code', - field=oscar.models.fields.NullCharField(max_length=255, unique=True, verbose_name='Code'), - ), - ] diff --git a/apps/catalogue/migrations/0019_option_required.py b/apps/catalogue/migrations/0019_option_required.py new file mode 100644 index 0000000..9798dc7 --- /dev/null +++ b/apps/catalogue/migrations/0019_option_required.py @@ -0,0 +1,37 @@ +# Generated by Django 2.1 on 2019-06-17 17:42 + +from django.db import migrations, models + + +def migrate_product_options(apps, schema_editor): + """ + Migrate product Option.type field to required + Set Option.type='text' + """ + Option = apps.get_model('catalogue', 'Option') + for option in Option.objects.all(): + if option.type == "Required": + option.required = True + option.type = 'text' + option.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0018_auto_20191220_0920'), + ] + + operations = [ + migrations.AddField( + model_name='option', + name='required', + field=models.BooleanField(default=False, verbose_name='Is option required?'), + ), + migrations.RunPython(migrate_product_options, migrations.RunPython.noop), + migrations.AlterField( + model_name='option', + name='type', + field=models.CharField(choices=[('text', 'Text'), ('integer', 'Integer'), ('boolean', 'True / False'), ('float', 'Float'), ('date', 'Date')], default='text', max_length=255, verbose_name='Type'), + ), + ] diff --git a/apps/catalogue/migrations/0020_auto_20200801_0817.py b/apps/catalogue/migrations/0020_auto_20200801_0817.py new file mode 100644 index 0000000..5ffe51a --- /dev/null +++ b/apps/catalogue/migrations/0020_auto_20200801_0817.py @@ -0,0 +1,27 @@ +# Generated by Django 3.0.8 on 2020-08-01 07:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0019_option_required'), + ] + + operations = [ + migrations.AlterModelOptions( + name='option', + options={'ordering': ['name'], 'verbose_name': 'Option', 'verbose_name_plural': 'Options'}, + ), + migrations.AlterField( + model_name='option', + name='name', + field=models.CharField(db_index=True, max_length=128, verbose_name='Name'), + ), + migrations.AlterField( + model_name='option', + name='required', + field=models.BooleanField(default=False, verbose_name='Is this option required?'), + ), + ] diff --git a/apps/catalogue/migrations/0021_auto_20201005_0844.py b/apps/catalogue/migrations/0021_auto_20201005_0844.py new file mode 100644 index 0000000..ad05f90 --- /dev/null +++ b/apps/catalogue/migrations/0021_auto_20201005_0844.py @@ -0,0 +1,33 @@ +# Generated by Django 3.0.10 on 2020-10-05 07:44 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0020_auto_20200801_0817'), + ] + + operations = [ + migrations.AddField( + model_name='category', + name='meta_description', + field=models.TextField(blank=True, null=True, verbose_name='Meta description'), + ), + migrations.AddField( + model_name='category', + name='meta_title', + field=models.CharField(blank=True, null=True, max_length=255, verbose_name='Meta title'), + ), + migrations.AddField( + model_name='product', + name='meta_description', + field=models.TextField(blank=True, null=True, verbose_name='Meta description'), + ), + migrations.AddField( + model_name='product', + name='meta_title', + field=models.CharField(blank=True, null=True, max_length=255, verbose_name='Meta title'), + ), + ] diff --git a/apps/catalogue/migrations/0022_auto_20210210_0539.py b/apps/catalogue/migrations/0022_auto_20210210_0539.py new file mode 100644 index 0000000..ea8988d --- /dev/null +++ b/apps/catalogue/migrations/0022_auto_20210210_0539.py @@ -0,0 +1,18 @@ +# Generated by Django 3.1.6 on 2021-02-10 05:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0021_auto_20201005_0844'), + ] + + operations = [ + migrations.AlterField( + model_name='productattributevalue', + name='value_boolean', + field=models.BooleanField(blank=True, db_index=True, null=True, verbose_name='Boolean'), + ), + ] diff --git a/apps/catalogue/migrations/0023_auto_20210824_1414.py b/apps/catalogue/migrations/0023_auto_20210824_1414.py new file mode 100644 index 0000000..aaca47b --- /dev/null +++ b/apps/catalogue/migrations/0023_auto_20210824_1414.py @@ -0,0 +1,19 @@ +# Generated by Django 3.1.4 on 2021-08-24 13:14 + +import oscar.models.fields.slugfield +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0022_auto_20210210_0539'), + ] + + operations = [ + migrations.AlterField( + model_name='product', + name='slug', + field=oscar.models.fields.slugfield.SlugField(max_length=255, verbose_name='Slug'), + ), + ] diff --git a/apps/catalogue/migrations/0024_remove_duplicate_attributes.py b/apps/catalogue/migrations/0024_remove_duplicate_attributes.py new file mode 100644 index 0000000..8e25175 --- /dev/null +++ b/apps/catalogue/migrations/0024_remove_duplicate_attributes.py @@ -0,0 +1,106 @@ +# Generated by Django 3.2.9 on 2022-01-25 19:01 +import logging + +from django.db import migrations +from django.db.models import CharField, Count, Value +from django.db.models.functions import Concat + +logger = logging.getLogger(__name__) + + +def get_value(attribute_value): + typ = attribute_value.attribute.type + field_name = "value_%s" % typ + value = getattr(attribute_value, field_name) + if hasattr(value, "all"): + value = value.all() + return value + +def remove_duplicate_attributes(apps, schema_editor): + """ + Removes duplicate attributes that have the same code and product class. + """ + ProductAttribute = apps.get_model('catalogue', 'ProductAttribute') + ProductAttributeValue = apps.get_model('catalogue', 'ProductAttributeValue') + ProductClass = apps.get_model("catalogue", "ProductClass") + + # Instead of iterating over all attributes, we concat the code and product class pk + # with a "|" so we can find duplicate attributes in one query. + duplicate_attributes = ProductAttribute.objects.filter(product_class__isnull=False).annotate( + code_and_product_class=Concat('code', Value('|'), 'product_class__pk', output_field=CharField()) + ).values('code_and_product_class').annotate( + same_code_count=Count('code_and_product_class') + ).filter(same_code_count__gt=1) + + for attribute in duplicate_attributes: + attribute_code, product_class_pk = attribute["code_and_product_class"].split("|") + product_class = ProductClass.objects.get(pk=product_class_pk) + attributes = ProductAttribute.objects.filter( + code=attribute_code, + product_class=product_class + ) + used_attributes = attributes.filter(productattributevalue__isnull=False) + used_attribute_count = used_attributes.distinct().count() + + # In most cases, the used attributes count will be one or zero as + # the dashboard will always show one attribute. If the used attribute + # count is one, we exclude this from attributes and remove the others. + # If it's zero, we pick the last created and delete others. + if used_attribute_count == 1: + attributes.exclude(pk=used_attributes.first().pk).delete() + continue + elif used_attribute_count == 0: + attributes.exclude(pk=attributes.last().pk).delete() + continue + + # If we found multiple attributes that have values linked to them, + # we must move them to one attribute and then delete the others. + # We can only do this if the value_types are all the same! + ASSERTION_MESSAGE = """Duplicate attribute found with code: %s but different types! + You could fix this by renaming the duplicate codes or by matching all types to one + type and update the attribute values accordingly for their new type. After that you can + re-run the migration.""" % attribute_code + assert used_attributes.values("type").distinct().count() == 1, ASSERTION_MESSAGE + + # Choose one attribute that will be used to move to and others to be deleted. + to_be_used_attribute = used_attributes.first() + to_be_deleted_attributes = used_attributes.exclude(pk=to_be_used_attribute.pk) + + for attribute in to_be_deleted_attributes: + for attribute_value in attribute.productattributevalue_set.all(): + product = attribute_value.product + + # ProductAttributeValue has a unique together constraint on 'product' and 'attribute'. + # This means, if the product of the current 'attribute_value' already has a ProductAttributeValue + # linked to the 'to_be_used_attribute' attribute, we can't update the attribute on the + # 'attribute_value' as this would raise an IntegrityError. + to_be_used_attribute_value = to_be_used_attribute.productattributevalue_set.filter(product=product).first() + if not to_be_used_attribute_value: + attribute_value.attribute = to_be_used_attribute + attribute_value.save() + else: + msg = """Product with ID '%s' had more than one attribute value linked to an attribute + with code '%s'. We've kept the value '%s' and removed the value '%s' as this is the one you + would see in the dashboard when editing the product. + """ % ( + product.id, + attribute.code, + get_value(to_be_used_attribute_value), + get_value(attribute_value) + ) + logger.warning(msg) + + # Once the attribute values have been updated, we can safely remove the attribute instance. + attribute.delete() + + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0023_auto_20210824_1414'), + ] + + operations = [ + migrations.RunPython(remove_duplicate_attributes, migrations.RunPython.noop) + ] diff --git a/apps/catalogue/migrations/0025_attribute_code_uniquetogether_constraint.py b/apps/catalogue/migrations/0025_attribute_code_uniquetogether_constraint.py new file mode 100644 index 0000000..4791df5 --- /dev/null +++ b/apps/catalogue/migrations/0025_attribute_code_uniquetogether_constraint.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.9 on 2022-01-25 20:17 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0024_remove_duplicate_attributes'), + ] + + operations = [ + migrations.AlterUniqueTogether( + name='productattribute', + unique_together={('code', 'product_class')}, + ), + ] diff --git a/apps/catalogue/migrations/0026_predefined_product_options.py b/apps/catalogue/migrations/0026_predefined_product_options.py new file mode 100644 index 0000000..9d31e89 --- /dev/null +++ b/apps/catalogue/migrations/0026_predefined_product_options.py @@ -0,0 +1,38 @@ +# Generated by Django 3.2.8 on 2021-10-27 11:42 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0025_attribute_code_uniquetogether_constraint'), + ] + + operations = [ + migrations.AlterModelOptions( + name='option', + options={'ordering': ['order', 'name'], 'verbose_name': 'Option', 'verbose_name_plural': 'Options'}, + ), + migrations.AddField( + model_name='option', + name='help_text', + field=models.CharField(blank=True, help_text='Help text shown to the user on the add to basket form', max_length=255, null=True, verbose_name='Help text'), + ), + migrations.AddField( + model_name='option', + name='option_group', + field=models.ForeignKey(blank=True, help_text='Select an option group if using type "Option" or "Multi Option"', null=True, on_delete=django.db.models.deletion.CASCADE, related_name='product_options', to='catalogue.attributeoptiongroup', verbose_name='Option Group'), + ), + migrations.AddField( + model_name='option', + name='order', + field=models.IntegerField(blank=True, db_index=True, help_text='Controls the ordering of product options on product detail pages', null=True, verbose_name='Ordering'), + ), + migrations.AlterField( + model_name='option', + name='type', + field=models.CharField(choices=[('text', 'Text'), ('integer', 'Integer'), ('boolean', 'True / False'), ('float', 'Float'), ('date', 'Date'), ('select', 'Select'), ('radio', 'Radio'), ('multi_select', 'Multi select'), ('checkbox', 'Checkbox')], default='text', max_length=255, verbose_name='Type'), + ), + ] diff --git a/apps/catalogue/migrations/0027_attributeoption_code_attributeoptiongroup_code_and_more.py b/apps/catalogue/migrations/0027_attributeoption_code_attributeoptiongroup_code_and_more.py new file mode 100644 index 0000000..9937968 --- /dev/null +++ b/apps/catalogue/migrations/0027_attributeoption_code_attributeoptiongroup_code_and_more.py @@ -0,0 +1,41 @@ +# Generated by Django 4.2.6 on 2023-12-20 17:10 + +import oscar.models.fields +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("catalogue", "0026_predefined_product_options"), + ] + + operations = [ + migrations.AddField( + model_name="attributeoption", + name="code", + field=oscar.models.fields.NullCharField( + max_length=255, unique=True, verbose_name="Unique identifier" + ), + ), + migrations.AddField( + model_name="attributeoptiongroup", + name="code", + field=oscar.models.fields.NullCharField( + max_length=255, unique=True, verbose_name="Unique identifier" + ), + ), + migrations.AddField( + model_name="category", + name="code", + field=oscar.models.fields.NullCharField( + max_length=255, unique=True, verbose_name="Code" + ), + ), + migrations.AddField( + model_name="productimage", + name="code", + field=oscar.models.fields.NullCharField( + max_length=255, unique=True, verbose_name="Code" + ), + ), + ] diff --git a/apps/catalogue/migrations/0028_product_priority.py b/apps/catalogue/migrations/0028_product_priority.py new file mode 100644 index 0000000..01bb2ce --- /dev/null +++ b/apps/catalogue/migrations/0028_product_priority.py @@ -0,0 +1,25 @@ +# Generated by Django 4.2.15 on 2024-09-11 10:37 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("catalogue", "0027_attributeoption_code_attributeoptiongroup_code_and_more"), + ] + + operations = [ + migrations.AddField( + model_name="product", + name="priority", + field=models.SmallIntegerField( + db_index=True, + default=0, + help_text="The highest priority products are shown first", + validators=[django.core.validators.MinValueValidator(-1)], + verbose_name="Priority", + ), + ), + ] diff --git a/apps/catalogue/migrations/0029_product_code.py b/apps/catalogue/migrations/0029_product_code.py new file mode 100644 index 0000000..2748db9 --- /dev/null +++ b/apps/catalogue/migrations/0029_product_code.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.5 on 2024-12-04 07:59 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("catalogue", "0028_product_priority"), + ] + + operations = [ + migrations.AddField( + model_name="product", + name="code", + field=models.CharField( + blank=True, + max_length=255, + null=True, + unique=True, + verbose_name="Code can be used to store a secondary unique identifier, when upc isn't sufficient", + ), + ), + ] diff --git a/apps/communication/migrations/0001_initial.py b/apps/communication/migrations/0001_initial.py index 1269133..609e07b 100644 --- a/apps/communication/migrations/0001_initial.py +++ b/apps/communication/migrations/0001_initial.py @@ -2,12 +2,11 @@ # Generated by Django 1.11.10 on 2018-02-18 10:32 from __future__ import unicode_literals -from django.conf import settings -from django.db import migrations, models import django.db.models.deletion import oscar.models.fields.autoslugfield -from django.utils.module_loading import import_string from django.conf import settings +from django.db import migrations, models +from django.utils.module_loading import import_string models_AutoField = import_string(settings.DEFAULT_AUTO_FIELD) diff --git a/apps/communication/migrations/0003_remove_notification_category_make_code_uppercase.py b/apps/communication/migrations/0003_remove_notification_category_make_code_uppercase.py index 4454e06..5ecce91 100644 --- a/apps/communication/migrations/0003_remove_notification_category_make_code_uppercase.py +++ b/apps/communication/migrations/0003_remove_notification_category_make_code_uppercase.py @@ -1,7 +1,7 @@ # Generated by Django 2.0.13 on 2019-05-26 08:03 import django.core.validators -from django.db import migrations import oscar.models.fields.autoslugfield +from django.db import migrations class Migration(migrations.Migration): diff --git a/apps/customer/migrations/0001_initial.py b/apps/customer/migrations/0001_initial.py index dc4e1bd..0c49ae0 100644 --- a/apps/customer/migrations/0001_initial.py +++ b/apps/customer/migrations/0001_initial.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations import oscar.models.fields.autoslugfield from django.conf import settings +from django.db import models, migrations class Migration(migrations.Migration): diff --git a/apps/customer/migrations/0002_auto_20150807_1725.py b/apps/customer/migrations/0002_auto_20150807_1725.py index 2e724f7..90ac4e0 100644 --- a/apps/customer/migrations/0002_auto_20150807_1725.py +++ b/apps/customer/migrations/0002_auto_20150807_1725.py @@ -1,9 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations -import oscar.models.fields.autoslugfield import django.core.validators +import oscar.models.fields.autoslugfield +from django.db import migrations class Migration(migrations.Migration): diff --git a/apps/customer/migrations/0004_email_save.py b/apps/customer/migrations/0004_email_save.py index 38fe407..d246235 100644 --- a/apps/customer/migrations/0004_email_save.py +++ b/apps/customer/migrations/0004_email_save.py @@ -2,9 +2,9 @@ # Generated by Django 1.10.7 on 2017-04-13 17:53 from __future__ import unicode_literals +import django.db.models.deletion from django.conf import settings from django.db import migrations, models -import django.db.models.deletion class Migration(migrations.Migration): diff --git a/apps/dashboard/apps.py b/apps/dashboard/apps.py index 6f3f2af..e1b1730 100644 --- a/apps/dashboard/apps.py +++ b/apps/dashboard/apps.py @@ -1,6 +1,6 @@ import oscar.apps.dashboard.apps as apps from django.apps import apps as django_apps -from django.conf.urls import include, url +from django.urls import include, path class DashboardConfig(apps.DashboardConfig): @@ -16,29 +16,29 @@ def get_urls(self): from django.contrib.auth import views as auth_views from django.contrib.auth.forms import AuthenticationForm urls = [ - url(r'^$', self.index_view.as_view(), name='index'), - url(r'^catalogue/', include(self.catalogue_app.urls[0])), - url(r'^reports/', include(self.reports_app.urls[0])), - url(r'^orders/', include(self.orders_app.urls[0])), - url(r'^users/', include(self.users_app.urls[0])), - url(r'^pages/', include(self.pages_app.urls[0])), - url(r'^partners/', include(self.partners_app.urls[0])), - url(r'^offers/', include(self.offers_app.urls[0])), - url(r'^ranges/', include(self.ranges_app.urls[0])), - url(r'^reviews/', include(self.reviews_app.urls[0])), - url(r'^vouchers/', include(self.vouchers_app.urls[0])), - url(r'^comms/', include(self.comms_app.urls[0])), - url(r'^shipping/', include(self.shipping_app.urls[0])), - url(r'^partner-configurable-menu/', - include((self.configurable_menu_app.urls[0], 'configurable_menu'), namespace='configurable_menu')), - url(r'^payment/', - include((self.dashboard_payment_app.urls[0], 'dashboard_payment'), namespace='dashboard_payment')), - url(r'^login/$', - auth_views.LoginView.as_view(template_name='oscar/dashboard/login.html', - authentication_form=AuthenticationForm), - name='login'), - url(r'^logout/$', auth_views.LogoutView.as_view(next_page='/'), name='logout'), - url(r'^banners/', - include((self.dashboard_banners_app.urls[0], 'dashboard_banners'), namespace='dashboard_banners')), + path('', self.index_view.as_view(), name='index'), + path('catalogue/', include(self.catalogue_app.urls[0])), + path('reports/', include(self.reports_app.urls[0])), + path('orders/', include(self.orders_app.urls[0])), + path('users/', include(self.users_app.urls[0])), + path('pages/', include(self.pages_app.urls[0])), + path('partners/', include(self.partners_app.urls[0])), + path('offers/', include(self.offers_app.urls[0])), + path('ranges/', include(self.ranges_app.urls[0])), + path('reviews/', include(self.reviews_app.urls[0])), + path('vouchers/', include(self.vouchers_app.urls[0])), + path('comms/', include(self.comms_app.urls[0])), + path('shipping/', include(self.shipping_app.urls[0])), + path('partner-configurable-menu/', + include((self.configurable_menu_app.urls[0], 'configurable_menu'), namespace='configurable_menu')), + path('payment/', + include((self.dashboard_payment_app.urls[0], 'dashboard_payment'), namespace='dashboard_payment')), + path('login/$', + auth_views.LoginView.as_view(template_name='oscar/dashboard/login.html', + authentication_form=AuthenticationForm), + name='login'), + path('logout/$', auth_views.LogoutView.as_view(next_page='/'), name='logout'), + path('banners/', + include((self.dashboard_banners_app.urls[0], 'dashboard_banners'), namespace='dashboard_banners')), ] return self.post_process_urls(urls) diff --git a/apps/dashboard/banners/migrations/0001_initial.py b/apps/dashboard/banners/migrations/0001_initial.py index c787f74..c93f9ae 100644 --- a/apps/dashboard/banners/migrations/0001_initial.py +++ b/apps/dashboard/banners/migrations/0001_initial.py @@ -1,9 +1,10 @@ # Generated by Django 2.2.5 on 2020-07-03 15:14 -import apps.dashboard.banners.models -from django.db import migrations, models import django.db.models.deletion import oscar.models.fields.autoslugfield +from django.db import migrations, models + +import apps.dashboard.banners.models class Migration(migrations.Migration): diff --git a/apps/dashboard/banners/tables.py b/apps/dashboard/banners/tables.py index 7908d56..d19f537 100644 --- a/apps/dashboard/banners/tables.py +++ b/apps/dashboard/banners/tables.py @@ -1,4 +1,3 @@ -from django.utils.translation import ungettext_lazy from django_tables2 import TemplateColumn from oscar.core.loading import get_class, get_model @@ -7,7 +6,7 @@ class BannerTable(DashboardTable): - caption = ungettext_lazy("%d Banner", "%d Banner") + caption = "%d Banner" actions = TemplateColumn( template_name='banners/dashboard/partials/actions.html', orderable=False) diff --git a/apps/dashboard/banners/templatetags/banner_tags.py b/apps/dashboard/banners/templatetags/banner_tags.py index e091f1c..764a953 100644 --- a/apps/dashboard/banners/templatetags/banner_tags.py +++ b/apps/dashboard/banners/templatetags/banner_tags.py @@ -1,8 +1,9 @@ +import logging + from django import template from django.template.loader import select_template from apps.dashboard.banners.models import Banner -import logging logger = logging.getLogger(__name__) register = template.Library() diff --git a/apps/dashboard/configurable_menu/apps.py b/apps/dashboard/configurable_menu/apps.py index 9361eed..a32d5dc 100644 --- a/apps/dashboard/configurable_menu/apps.py +++ b/apps/dashboard/configurable_menu/apps.py @@ -1,5 +1,5 @@ # from django.conf.urls import include, url # < Django-2.0 -from django.urls import include, path # > Django-2.0 +from django.urls import path # > Django-2.0 from django.utils.translation import gettext_lazy as _ from oscar.core.application import OscarDashboardConfig from oscar.core.loading import get_class diff --git a/apps/dashboard/configurable_menu/migrations/0001_initial.py b/apps/dashboard/configurable_menu/migrations/0001_initial.py index 5b02693..f641953 100644 --- a/apps/dashboard/configurable_menu/migrations/0001_initial.py +++ b/apps/dashboard/configurable_menu/migrations/0001_initial.py @@ -1,8 +1,8 @@ # Generated by Django 2.2.5 on 2019-12-08 15:02 -from django.db import migrations, models import django.db.models.deletion import oscar.models.fields.slugfield +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/apps/dashboard/configurable_menu/migrations/0002_partnerconfigurablemenuitem_patner_menu.py b/apps/dashboard/configurable_menu/migrations/0002_partnerconfigurablemenuitem_patner_menu.py index 241c10d..c7a58de 100644 --- a/apps/dashboard/configurable_menu/migrations/0002_partnerconfigurablemenuitem_patner_menu.py +++ b/apps/dashboard/configurable_menu/migrations/0002_partnerconfigurablemenuitem_patner_menu.py @@ -1,7 +1,7 @@ # Generated by Django 2.2.5 on 2019-12-08 15:14 -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/apps/dashboard/configurable_menu/migrations/0003_partnerconfigurablemenu_partner.py b/apps/dashboard/configurable_menu/migrations/0003_partnerconfigurablemenu_partner.py index 26e290e..fec370e 100644 --- a/apps/dashboard/configurable_menu/migrations/0003_partnerconfigurablemenu_partner.py +++ b/apps/dashboard/configurable_menu/migrations/0003_partnerconfigurablemenu_partner.py @@ -1,7 +1,7 @@ # Generated by Django 2.2.5 on 2020-01-03 19:03 -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/apps/dashboard/configurable_menu/migrations/0008_partnerconfigurablemenuitem_code.py b/apps/dashboard/configurable_menu/migrations/0008_partnerconfigurablemenuitem_code.py index be3c675..a46f928 100644 --- a/apps/dashboard/configurable_menu/migrations/0008_partnerconfigurablemenuitem_code.py +++ b/apps/dashboard/configurable_menu/migrations/0008_partnerconfigurablemenuitem_code.py @@ -1,7 +1,7 @@ # Generated by Django 3.2.25 on 2024-08-07 15:38 -from django.db import migrations import oscar.models.fields +from django.db import migrations class Migration(migrations.Migration): diff --git a/apps/dashboard/configurable_menu/tables.py b/apps/dashboard/configurable_menu/tables.py index a558ad1..828d946 100644 --- a/apps/dashboard/configurable_menu/tables.py +++ b/apps/dashboard/configurable_menu/tables.py @@ -1,5 +1,5 @@ from django.utils.safestring import mark_safe -from django.utils.translation import gettext_lazy as _, ungettext_lazy +from django.utils.translation import gettext_lazy as _, ngettext_lazy from django_tables2 import LinkColumn, TemplateColumn, A from oscar.core.loading import get_class, get_model @@ -9,7 +9,7 @@ class MenuTable(DashboardTable): - caption = ungettext_lazy("%d Menu", "%d Menus") + caption = ngettext_lazy("%d Menu", "%d Menus") actions = TemplateColumn( template_name='oscar/dashboard/configurable_menu/menu_row_actions.html', orderable=False) @@ -36,7 +36,7 @@ class MenuItemTable(DashboardTable): orderable=False) icon = "sitemap" - caption = ungettext_lazy("%s Menu Item", "%s Menu Items") + caption = ngettext_lazy("%s Menu Item", "%s Menu Items") class Meta(DashboardTable.Meta): model = PartnerConfigurableMenuItem diff --git a/apps/dashboard/dashboard_payment/apps.py b/apps/dashboard/dashboard_payment/apps.py index 65ba9b7..4122335 100644 --- a/apps/dashboard/dashboard_payment/apps.py +++ b/apps/dashboard/dashboard_payment/apps.py @@ -1,4 +1,4 @@ -from django.conf.urls import url +from django.urls import path from django.utils.translation import gettext_lazy as _ from oscar.core.application import OscarDashboardConfig @@ -46,34 +46,43 @@ def ready(self): def get_urls(self): urls = [ - url(r'^bankcards/$', self.bankcard_list_view.as_view(), name='bankcards-list'), - url(r'^bankcard/create/$', self.bankcard_create_view.as_view(), name='bankcard-create'), - url(r'^bankcard/(?P\d+)/delete/$', self.bankcard_delete_view.as_view(), name='bankcard-delete'), - url(r'^bankcard/(?P\d+)/manage/$', self.bankcard_manage_view.as_view(), name='bankcard-manage'), - - url(r'^sources/$', self.source_list_view.as_view(), name='sources-list'), - url(r'^source/create/$', self.source_create_view.as_view(), name='source-create'), - url(r'^source/(?P\d+)/delete/$', self.source_delete_view.as_view(), name='source-delete'), - url(r'^source/(?P\d+)/manage/$', self.source_manage_view.as_view(), name='source-manage'), - - url(r'^source-types/$', self.source_type_list_view.as_view(), name='source_types-list'), - url(r'^source-type/create/$', self.source_type_create_view.as_view(), name='source_type-create'), - url(r'^source-type/(?P\d+)/delete/$', self.source_type_delete_view.as_view(), name='source_type-delete'), - url(r'^source-type/(?P\d+)/manage/$', self.source_type_manage_view.as_view(), name='source_type-manage'), - - url(r'^transactions/$', self.transaction_list_view.as_view(), name='transactions-list'), - url(r'^transaction/create/$', self.transaction_create_view.as_view(), name='transaction-create'), - url(r'^transaction/(?P\d+)/delete/$', self.transaction_delete_view.as_view(), name='transaction-delete'), - url(r'^transaction/(?P\d+)/manage/$', self.transaction_manage_view.as_view(), name='transaction-manage'), - - url(r'^payment-methods/$', self.payment_method_list_view.as_view(), name='payment_methods-list'), - url(r'^payment-method/create/$', self.payment_method_create_view.as_view(), name='payment_method-create'), - url(r'^payment-method/(?P\d+)/delete/$', self.payment_method_delete_view.as_view(), name='payment_method-delete'), - url(r'^payment-method/(?P\d+)/manage/$', self.payment_method_manage_view.as_view(), name='payment_method-manage'), - - url(r'^payment-gateways/$', self.payment_gateway_list_view.as_view(), name='payment_gateways-list'), - url(r'^payment-gateway/create/$', self.payment_gateway_create_view.as_view(), name='payment_gateway-create'), - url(r'^payment-gateway/(?P\d+)/delete/$', self.payment_gateway_delete_view.as_view(), name='payment_gateway-delete'), - url(r'^payment-gateway/(?P\d+)/manage/$', self.payment_gateway_manage_view.as_view(), name='payment_gateway-manage'), + path('bankcards/', self.bankcard_list_view.as_view(), name='bankcards-list'), + path('bankcard/create/', self.bankcard_create_view.as_view(), name='bankcard-create'), + path('bankcard/(?P\d+)/delete/', self.bankcard_delete_view.as_view(), name='bankcard-delete'), + path('bankcard/(?P\d+)/manage/', self.bankcard_manage_view.as_view(), name='bankcard-manage'), + + path('sources/', self.source_list_view.as_view(), name='sources-list'), + path('source/create/', self.source_create_view.as_view(), name='source-create'), + path('source/(?P\d+)/delete/', self.source_delete_view.as_view(), name='source-delete'), + path('source/(?P\d+)/manage/', self.source_manage_view.as_view(), name='source-manage'), + + path('source-types/', self.source_type_list_view.as_view(), name='source_types-list'), + path('source-type/create/', self.source_type_create_view.as_view(), name='source_type-create'), + path('source-type/(?P\d+)/delete/', self.source_type_delete_view.as_view(), + name='source_type-delete'), + path('source-type/(?P\d+)/manage/', self.source_type_manage_view.as_view(), + name='source_type-manage'), + + path('transactions/', self.transaction_list_view.as_view(), name='transactions-list'), + path('transaction/create/', self.transaction_create_view.as_view(), name='transaction-create'), + path('transaction/(?P\d+)/delete/', self.transaction_delete_view.as_view(), + name='transaction-delete'), + path('transaction/(?P\d+)/manage/', self.transaction_manage_view.as_view(), + name='transaction-manage'), + + path('payment-methods/', self.payment_method_list_view.as_view(), name='payment_methods-list'), + path('payment-method/create/', self.payment_method_create_view.as_view(), name='payment_method-create'), + path('payment-method/(?P\d+)/delete/', self.payment_method_delete_view.as_view(), + name='payment_method-delete'), + path('payment-method/(?P\d+)/manage/', self.payment_method_manage_view.as_view(), + name='payment_method-manage'), + + path('payment-gateways/', self.payment_gateway_list_view.as_view(), name='payment_gateways-list'), + path('payment-gateway/create/', self.payment_gateway_create_view.as_view(), + name='payment_gateway-create'), + path('payment-gateway/(?P\d+)/delete/', self.payment_gateway_delete_view.as_view(), + name='payment_gateway-delete'), + path('payment-gateway/(?P\d+)/manage/', self.payment_gateway_manage_view.as_view(), + name='payment_gateway-manage'), ] return self.post_process_urls(urls) diff --git a/apps/dashboard/settings/apps.py b/apps/dashboard/settings/apps.py index 307c16e..17cf7e9 100644 --- a/apps/dashboard/settings/apps.py +++ b/apps/dashboard/settings/apps.py @@ -1,5 +1,6 @@ -from oscar.core.application import OscarDashboardConfig from django.utils.translation import gettext_lazy as _ +from oscar.core.application import OscarDashboardConfig + class SettingsConfig(OscarDashboardConfig): name = 'settings' diff --git a/apps/dashboard/settings/context_processors.py b/apps/dashboard/settings/context_processors.py index 785dbe4..df94b7d 100644 --- a/apps/dashboard/settings/context_processors.py +++ b/apps/dashboard/settings/context_processors.py @@ -1,5 +1,3 @@ -from django.conf import settings - from apps.dashboard.settings.models import Setting from apps.payment.models import PaymentMethod diff --git a/apps/dashboard/settings/migrations/0001_initial.py b/apps/dashboard/settings/migrations/0001_initial.py index 1e80a5f..c86c574 100644 --- a/apps/dashboard/settings/migrations/0001_initial.py +++ b/apps/dashboard/settings/migrations/0001_initial.py @@ -1,8 +1,9 @@ # Generated by Django 2.2.5 on 2020-05-29 19:17 -import apps.dashboard.settings.models from django.db import migrations, models +import apps.dashboard.settings.models + class Migration(migrations.Migration): diff --git a/apps/dashboard/settings/migrations/0004_auto_20200529_2031.py b/apps/dashboard/settings/migrations/0004_auto_20200529_2031.py index 53881f8..227dbd9 100644 --- a/apps/dashboard/settings/migrations/0004_auto_20200529_2031.py +++ b/apps/dashboard/settings/migrations/0004_auto_20200529_2031.py @@ -1,8 +1,9 @@ # Generated by Django 2.2.5 on 2020-05-29 20:31 -import apps.dashboard.settings.models from django.db import migrations, models +import apps.dashboard.settings.models + class Migration(migrations.Migration): diff --git a/apps/dashboard/settings/migrations/0006_auto_20210202_1402.py b/apps/dashboard/settings/migrations/0006_auto_20210202_1402.py index a26b581..4255c59 100644 --- a/apps/dashboard/settings/migrations/0006_auto_20210202_1402.py +++ b/apps/dashboard/settings/migrations/0006_auto_20210202_1402.py @@ -1,7 +1,7 @@ # Generated by Django 2.2.5 on 2021-02-02 14:02 -from django.db import migrations import django.db.models.manager +from django.db import migrations class Migration(migrations.Migration): diff --git a/apps/dashboard/settings/tests.py b/apps/dashboard/settings/tests.py index 7ce503c..a39b155 100644 --- a/apps/dashboard/settings/tests.py +++ b/apps/dashboard/settings/tests.py @@ -1,3 +1 @@ -from django.test import TestCase - # Create your tests here. diff --git a/apps/dashboard/settings/views.py b/apps/dashboard/settings/views.py index 91ea44a..60f00ef 100644 --- a/apps/dashboard/settings/views.py +++ b/apps/dashboard/settings/views.py @@ -1,3 +1 @@ -from django.shortcuts import render - # Create your views here. diff --git a/apps/partner/migrations/0001_initial.py b/apps/partner/migrations/0001_initial.py index 6f2de06..f3fe201 100644 --- a/apps/partner/migrations/0001_initial.py +++ b/apps/partner/migrations/0001_initial.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations -import oscar.models.fields.autoslugfield import oscar.models.fields +import oscar.models.fields.autoslugfield from django.conf import settings +from django.db import models, migrations class Migration(migrations.Migration): diff --git a/apps/partner/migrations/0002_auto_20141007_2032.py b/apps/partner/migrations/0002_auto_20141007_2032.py index 0baa7b0..179e0e7 100644 --- a/apps/partner/migrations/0002_auto_20141007_2032.py +++ b/apps/partner/migrations/0002_auto_20141007_2032.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations import oscar.core.utils +from django.db import models, migrations class Migration(migrations.Migration): diff --git a/apps/partner/migrations/0003_auto_20150604_1450.py b/apps/partner/migrations/0003_auto_20150604_1450.py index ffbe82c..ab3d46b 100644 --- a/apps/partner/migrations/0003_auto_20150604_1450.py +++ b/apps/partner/migrations/0003_auto_20150604_1450.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations from django.conf import settings +from django.db import models, migrations class Migration(migrations.Migration): diff --git a/apps/partner/migrations/0004_auto_20160107_1755.py b/apps/partner/migrations/0004_auto_20160107_1755.py index 93a0bec..2381ffc 100644 --- a/apps/partner/migrations/0004_auto_20160107_1755.py +++ b/apps/partner/migrations/0004_auto_20160107_1755.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations +from django.db import migrations class Migration(migrations.Migration): diff --git a/apps/payment/migrations/0001_initial.py b/apps/payment/migrations/0001_initial.py index c56f26e..9337bc0 100644 --- a/apps/payment/migrations/0001_initial.py +++ b/apps/payment/migrations/0001_initial.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations +from decimal import Decimal + import oscar.models.fields.autoslugfield from django.conf import settings -from decimal import Decimal +from django.db import models, migrations class Migration(migrations.Migration): diff --git a/apps/payment/migrations/0002_auto_20141007_2032.py b/apps/payment/migrations/0002_auto_20141007_2032.py index 559a061..4cce6ee 100644 --- a/apps/payment/migrations/0002_auto_20141007_2032.py +++ b/apps/payment/migrations/0002_auto_20141007_2032.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations import oscar.core.utils +from django.db import models, migrations class Migration(migrations.Migration): diff --git a/apps/payment/migrations/0005_paymentmethod.py b/apps/payment/migrations/0005_paymentmethod.py index f1a4884..7694ca8 100644 --- a/apps/payment/migrations/0005_paymentmethod.py +++ b/apps/payment/migrations/0005_paymentmethod.py @@ -1,7 +1,7 @@ # Generated by Django 2.2.5 on 2020-05-31 17:38 -from django.db import migrations, models import django.db.models.deletion +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/apps/payment/migrations/0006_paymentmethod_price_currency.py b/apps/payment/migrations/0006_paymentmethod_price_currency.py index dbb9627..a4b5a2f 100644 --- a/apps/payment/migrations/0006_paymentmethod_price_currency.py +++ b/apps/payment/migrations/0006_paymentmethod_price_currency.py @@ -1,7 +1,7 @@ # Generated by Django 2.2.5 on 2020-06-01 08:23 -from django.db import migrations, models import oscar.core.utils +from django.db import migrations, models class Migration(migrations.Migration): diff --git a/apps/shipping/migrations/0001_initial.py b/apps/shipping/migrations/0001_initial.py index 2344833..db10976 100644 --- a/apps/shipping/migrations/0001_initial.py +++ b/apps/shipping/migrations/0001_initial.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals -from django.db import models, migrations -import oscar.models.fields.autoslugfield from decimal import Decimal + import django.core.validators +import oscar.models.fields.autoslugfield +from django.db import models, migrations class Migration(migrations.Migration): diff --git a/apps/shipping/migrations/0003_auto_20181115_1953.py b/apps/shipping/migrations/0003_auto_20181115_1953.py index 7701b6b..9318c3f 100644 --- a/apps/shipping/migrations/0003_auto_20181115_1953.py +++ b/apps/shipping/migrations/0003_auto_20181115_1953.py @@ -1,6 +1,7 @@ # Generated by Django 2.0.7 on 2018-11-15 19:53 from decimal import Decimal + import django.core.validators from django.db import migrations, models diff --git a/docker-compose.yml b/docker-compose.yml index 8eac48e..bc98840 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,7 +43,7 @@ services: - redis.oscar.com postgres: restart: always - image: kiasaki/alpine-postgres:9.5 + image: bitnami/postgresql:latest container_name: com.primzel.psql hostname: psql.primzel.com environment: @@ -91,4 +91,4 @@ services: - com.stripe.cli networks: primzel-docker-network: - driver: bridge \ No newline at end of file + driver: bridge diff --git a/e_store_primzel/settings/install_apps.py b/e_store_primzel/settings/install_apps.py index 563e18f..5d52d9d 100644 --- a/e_store_primzel/settings/install_apps.py +++ b/e_store_primzel/settings/install_apps.py @@ -8,47 +8,53 @@ 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.flatpages', - 'oscar', - 'oscar.apps.analytics', - 'oscar.apps.address', - 'oscar.apps.catalogue.reviews', - 'oscar.apps.basket', - 'oscar.apps.offer', - 'oscar.apps.order', - 'oscar.apps.search', - 'oscar.apps.voucher', - 'oscar.apps.wishlists', - 'apps.dashboard', - 'oscar.apps.dashboard.reports', - 'oscar.apps.dashboard.users', - 'oscar.apps.dashboard.orders', + + 'oscar.config.Shop', + 'oscar.apps.analytics.apps.AnalyticsConfig', + 'oscar.apps.address.apps.AddressConfig', + 'oscar.apps.catalogue.reviews.apps.CatalogueReviewsConfig', + 'oscar.apps.basket.apps.BasketConfig', + 'oscar.apps.offer.apps.OfferConfig', + 'oscar.apps.order.apps.OrderConfig', + 'oscar.apps.search.apps.SearchConfig', + 'oscar.apps.voucher.apps.VoucherConfig', + 'oscar.apps.wishlists.apps.WishlistsConfig', + 'apps.dashboard.apps.DashboardConfig', + 'oscar.apps.dashboard.reports.apps.ReportsDashboardConfig', + 'oscar.apps.dashboard.users.apps.UsersDashboardConfig', + 'oscar.apps.dashboard.orders.apps.OrdersDashboardConfig', + 'apps.dashboard.catalogue', - 'oscar.apps.dashboard.offers', - 'oscar.apps.dashboard.ranges', - 'oscar.apps.dashboard.reviews', - 'oscar.apps.dashboard.vouchers', - 'oscar.apps.dashboard.communications', - 'oscar.apps.dashboard.shipping', + 'oscar.apps.dashboard.offers.apps.OffersDashboardConfig', + 'oscar.apps.dashboard.ranges.apps.RangesDashboardConfig', + 'oscar.apps.dashboard.reviews.apps.ReviewsDashboardConfig', + 'oscar.apps.dashboard.vouchers.apps.VouchersDashboardConfig', + 'oscar.apps.dashboard.communications.apps.CommunicationsDashboardConfig', + 'oscar.apps.dashboard.shipping.apps.ShippingDashboardConfig', 'sorl.thumbnail', 'colorfield', -]+[ +] + +PRIMZEL_APPS = [ # Primzel Apps 'apps.communication.apps.CommunicationConfig', 'apps.dashboard.pages', - 'apps.dashboard.configurable_menu', + 'apps.dashboard.configurable_menu.apps.ConfigurableMenuConfig', 'apps.checkout', 'apps.shipping', 'apps.dashboard.settings', 'apps.payment', - 'apps.dashboard.dashboard_payment', + 'apps.dashboard.dashboard_payment.apps.PaymentDashboardConfig', 'apps.dashboard.partners', 'apps.partner', 'apps.catalogue', - 'apps.dashboard.banners', + 'apps.dashboard.banners.apps.BannersConfig', 'apps.customer', 'primzel.global_signal_handler', ] +TENANT_APPS += PRIMZEL_APPS + SHARED_APPS = [ 'django_tenants', 'multitenancy', diff --git a/e_store_primzel/settings/navigation.py b/e_store_primzel/settings/navigation.py index 39b2857..ed35b3f 100644 --- a/e_store_primzel/settings/navigation.py +++ b/e_store_primzel/settings/navigation.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ from oscar.defaults import * OSCAR_DASHBOARD_NAVIGATION += [ diff --git a/e_store_primzel/settings/payment.py b/e_store_primzel/settings/payment.py index d8b291e..4176d4e 100644 --- a/e_store_primzel/settings/payment.py +++ b/e_store_primzel/settings/payment.py @@ -1,4 +1,4 @@ -from django.utils.translation import ugettext_lazy as _ +from django.utils.translation import gettext_lazy as _ OSCAR_PAYMENT_METHODS = ( ('cod', _('Cash on delivery')), diff --git a/requirements b/requirements index 53e7ec4..26755e0 100644 --- a/requirements +++ b/requirements @@ -1,5 +1,5 @@ -Django>=3.2,<4.0 # Django 2.2 is outdated; Django 3.2 is the next LTS release. -django-oscar==3.2.4 # Assuming compatibility with Django 3.2. +Django==5.2.5 # Updated to the latest stable version of Django. +django-oscar==4.0 # Updated to a newer version compatible with Django 3.2+. pycountry # Latest version, no specific version required. sorl-thumbnail # Latest version, no specific version required. gunicorn # Latest version, no specific version required. From 7988138a8cfcb5de56d2df7bac146c8786c74113 Mon Sep 17 00:00:00 2001 From: qasim Date: Fri, 5 Sep 2025 01:04:24 +0500 Subject: [PATCH 2/8] fix: upgrade oscar django --- apps/catalogue/search_handlers.py | 23 ----- e_store_primzel/settings/__init__.py | 1 - e_store_primzel/settings/base.py | 96 ++++++++++++++++++- e_store_primzel/settings/navigation.py | 63 ------------ e_store_primzel/urls.py | 13 +-- .../eggs/static/oscar/css/bootstrap.min.js | 7 ++ .../templates/oscar/partials/form_fields.html | 14 +-- 7 files changed, 112 insertions(+), 105 deletions(-) delete mode 100644 apps/catalogue/search_handlers.py delete mode 100644 e_store_primzel/settings/navigation.py create mode 100644 templates/eggs/static/oscar/css/bootstrap.min.js diff --git a/apps/catalogue/search_handlers.py b/apps/catalogue/search_handlers.py deleted file mode 100644 index 5a65eff..0000000 --- a/apps/catalogue/search_handlers.py +++ /dev/null @@ -1,23 +0,0 @@ -from oscar.apps.catalogue.search_handlers import SimpleProductSearchHandler as DefaultSimpleProductSearchHandler - -from oscar.core.loading import get_model - -Product = get_model('catalogue', 'Product') - - -class SimpleProductSearchHandler(DefaultSimpleProductSearchHandler): - - def __init__(self, request_data, full_path, categories=None): - self.categories = categories - self.request_data = request_data - self.kwargs = {'page': request_data.get('page', 1), 'partner': request_data.get('partner', None)} - self.object_list = self.get_queryset() - - def get_queryset(self): - qs = Product.objects.browsable().base_queryset() - partner = self.kwargs.get('partner') - if partner: - qs = qs.filter(stockrecords__partner__name=partner) - if self.categories: - qs = qs.filter(categories__in=self.categories).distinct() - return qs diff --git a/e_store_primzel/settings/__init__.py b/e_store_primzel/settings/__init__.py index d5e484b..4d0d579 100644 --- a/e_store_primzel/settings/__init__.py +++ b/e_store_primzel/settings/__init__.py @@ -7,7 +7,6 @@ from .templates import * from .database import * from .middleware import * -from .navigation import * from .application_defination import * from .multitenant import * from .aws import * diff --git a/e_store_primzel/settings/base.py b/e_store_primzel/settings/base.py index 218e8a1..8e56aec 100644 --- a/e_store_primzel/settings/base.py +++ b/e_store_primzel/settings/base.py @@ -11,6 +11,8 @@ """ import os +from django.utils.translation import gettext_lazy as _ + from oscar.defaults import * # Build paths inside the project like this: os.path.join(BASE_DIR, ...) @@ -94,4 +96,96 @@ # ... ] -EMAIL_BACKEND = os.getenv('EMAIL_BACKEND', 'django.core.mail.backends.console.EmailBackend') \ No newline at end of file +EMAIL_BACKEND = os.getenv('EMAIL_BACKEND', 'django.core.mail.backends.console.EmailBackend') +# Search facets +OSCAR_SEARCH_FACETS = { + "fields": { + # The key for these dicts will be used when passing facet data + # to the template. Same for the 'queries' dict below. + "product_class": {"name": _("Type"), "field": "product_class"}, + "rating": {"name": _("Rating"), "field": "rating"}, + # You can specify an 'options' element that will be passed to the + # SearchQuerySet.facet() call. + # For instance, with Elasticsearch backend, 'options': {'order': 'term'} + # will sort items in a facet by title instead of number of items. + # It's hard to get 'missing' to work + # correctly though as of Solr's hilarious syntax for selecting + # items without a specific facet: + # http://wiki.apache.org/solr/SimpleFacetParameters#facet.method + # 'options': {'missing': 'true'} + }, + "queries": { + "price_range": { + "name": _("Price range"), + "field": "price", + "queries": [ + # This is a list of (name, query) tuples where the name will + # be displayed on the front-end. + (_("0 to 20"), "[0 TO 20]"), + (_("20 to 40"), "[20 TO 40]"), + (_("40 to 60"), "[40 TO 60]"), + (_("60+"), "[60 TO *]"), + ], + }, + }, +} +OSCAR_DASHBOARD_NAVIGATION += [ + { + 'label': _('Configurable Partner Menu'), + 'icon': 'glyphicon-tree-conifer', + 'children': [ + { + 'label': _('Create Menu'), + 'url_name': 'dashboard:configurable_menu:partner-configurable-menu-create', + }, + { + 'label': _('All Menus'), + 'url_name': 'dashboard:configurable_menu:partner-configurable-menu-listing', + } + ] + }, + { + 'label': _('Payment'), + 'icon': 'glyphicon-usd', + 'children': [ + { + 'label': _('Bankcards'), + 'url_name': 'dashboard:dashboard_payment:bankcards-list', + }, + { + 'label': _('Payment methods'), + 'url_name': 'dashboard:dashboard_payment:payment_methods-list', + }, + { + 'label': _('Source Types'), + 'url_name': 'dashboard:dashboard_payment:source_types-list', + }, + { + 'label': _('Sources'), + 'url_name': 'dashboard:dashboard_payment:sources-list', + }, + { + 'label': _('Transactions'), + 'url_name': 'dashboard:dashboard_payment:transactions-list', + }, + { + 'label': _('Available payment gateways'), + 'url_name': 'dashboard:dashboard_payment:payment_gateways-list', + }, + ] + }, + { + 'label': _('Settings'), + 'icon': 'glyphicon-tree-conifer', + 'children': [ + { + 'label': _('Banners'), + 'url_name': 'dashboard:dashboard_banners:banners-listing', + }, + { + 'label': _('New Banner'), + 'url_name': 'dashboard:dashboard_banners:banners-create', + } + ] + } +] diff --git a/e_store_primzel/settings/navigation.py b/e_store_primzel/settings/navigation.py deleted file mode 100644 index ed35b3f..0000000 --- a/e_store_primzel/settings/navigation.py +++ /dev/null @@ -1,63 +0,0 @@ -from django.utils.translation import gettext_lazy as _ -from oscar.defaults import * - -OSCAR_DASHBOARD_NAVIGATION += [ - { - 'label': _('Configurable Partner Menu'), - 'icon': 'glyphicon-tree-conifer', - 'children': [ - { - 'label': _('Create Menu'), - 'url_name': 'dashboard:configurable_menu:partner-configurable-menu-create', - }, - { - 'label': _('All Menus'), - 'url_name': 'dashboard:configurable_menu:partner-configurable-menu-listing', - } - ] - }, - { - 'label': _('Payment'), - 'icon': 'glyphicon-usd', - 'children': [ - { - 'label': _('Bankcards'), - 'url_name': 'dashboard:dashboard_payment:bankcards-list', - }, - { - 'label': _('Payment methods'), - 'url_name': 'dashboard:dashboard_payment:payment_methods-list', - }, - { - 'label': _('Source Types'), - 'url_name': 'dashboard:dashboard_payment:source_types-list', - }, - { - 'label': _('Sources'), - 'url_name': 'dashboard:dashboard_payment:sources-list', - }, - { - 'label': _('Transactions'), - 'url_name': 'dashboard:dashboard_payment:transactions-list', - }, - { - 'label': _('Available payment gateways'), - 'url_name': 'dashboard:dashboard_payment:payment_gateways-list', - }, - ] - }, - { - 'label': _('Settings'), - 'icon': 'glyphicon-tree-conifer', - 'children': [ - { - 'label': _('Banners'), - 'url_name': 'dashboard:dashboard_banners:banners-listing', - }, - { - 'label': _('New Banner'), - 'url_name': 'dashboard:dashboard_banners:banners-create', - } - ] - } -] diff --git a/e_store_primzel/urls.py b/e_store_primzel/urls.py index 37b0e70..ec061e8 100644 --- a/e_store_primzel/urls.py +++ b/e_store_primzel/urls.py @@ -13,12 +13,12 @@ 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ +from debug_toolbar.toolbar import debug_toolbar_urls from django.apps import apps from django.conf import settings +from django.contrib import admin from django.contrib.staticfiles.urls import staticfiles_urlpatterns -# from django.conf.urls import include, url # < Django-2.0 from django.urls import include, path # > Django-2.0 -from django.contrib import admin from django.views.decorators.csrf import csrf_exempt from primzel.payment_gateways.views import IPNActionView @@ -40,13 +40,6 @@ urlpatterns += staticfiles_urlpatterns() if settings.DEBUG: - import debug_toolbar from django.urls import path - urlpatterns = [ - path('__debug__/', include(debug_toolbar.urls)), - - # For django versions before 2.0: - # url(r'^__debug__/', include(debug_toolbar.urls)), - - ] + urlpatterns + urlpatterns = debug_toolbar_urls() + urlpatterns diff --git a/templates/eggs/static/oscar/css/bootstrap.min.js b/templates/eggs/static/oscar/css/bootstrap.min.js new file mode 100644 index 0000000..9bcd2fc --- /dev/null +++ b/templates/eggs/static/oscar/css/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.7 (http://getbootstrap.com) + * Copyright 2011-2016 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1||b[0]>3)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){if(a(b.target).is(this))return b.handleObj.handler.apply(this,arguments)}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.7",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a("#"===f?[]:f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.7",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c).prop(c,!0)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c).prop(c,!1))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target).closest(".btn");b.call(d,"toggle"),a(c.target).is('input[type="radio"], input[type="checkbox"]')||(c.preventDefault(),d.is("input,button")?d.trigger("focus"):d.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.7",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(a>this.$items.length-1||a<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){if(!this.sliding)return this.slide("next")},c.prototype.prev=function(){if(!this.sliding)return this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.7",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger(a.Event("hidden.bs.dropdown",f)))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.7",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger(a.Event("shown.bs.dropdown",h))}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);if(c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),!c.isInStateTrue())return clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide()},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null,a.$element=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;!e&&/destroy|hide/.test(b)||(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.7",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.7",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.7",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return e=a-d&&"bottom"},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/templates/eggs/templates/oscar/partials/form_fields.html b/templates/eggs/templates/oscar/partials/form_fields.html index 68290b9..226f04f 100644 --- a/templates/eggs/templates/oscar/partials/form_fields.html +++ b/templates/eggs/templates/oscar/partials/form_fields.html @@ -15,14 +15,14 @@ {% endif %}
{% for field in form %} - {% ifequal forloop.counter|divisibleby:"2" True %} + {% if forloop.counter|divisibleby:4 == True %} +
+ {% endif %} + {% if forloop.counter|divisibleby:4 == True %}
- {% endifequal %} -
+ {% endif %} +
{% include 'oscar/partials/form_field.html' with field=field style=style %}
- {% ifequal forloop.counter|divisibleby:"2" False %} -
- {% endifequal %} {% endfor %} -
\ No newline at end of file + From ee83f6e2eb02a84883ccbb90f87c9bf14fb943bc Mon Sep 17 00:00:00 2001 From: qasim Date: Thu, 18 Sep 2025 19:46:02 +0500 Subject: [PATCH 3/8] fix: override search query for default landing page --- apps/search/__init__.py | 1 + apps/search/apps.py | 5 + apps/search/facets.py | 18 ++++ apps/search/search_indexes.py | 111 +++++++++++++++++++++++ e_store_primzel/settings/base.py | 25 ----- e_store_primzel/settings/install_apps.py | 2 +- 6 files changed, 136 insertions(+), 26 deletions(-) create mode 100644 apps/search/__init__.py create mode 100644 apps/search/apps.py create mode 100644 apps/search/facets.py create mode 100644 apps/search/search_indexes.py diff --git a/apps/search/__init__.py b/apps/search/__init__.py new file mode 100644 index 0000000..2e1f10f --- /dev/null +++ b/apps/search/__init__.py @@ -0,0 +1 @@ +default_app_config = 'apps.search.apps.SearchConfig' diff --git a/apps/search/apps.py b/apps/search/apps.py new file mode 100644 index 0000000..1e0befc --- /dev/null +++ b/apps/search/apps.py @@ -0,0 +1,5 @@ +import oscar.apps.search.apps as apps + + +class SearchConfig(apps.SearchConfig): + name = 'apps.search' diff --git a/apps/search/facets.py b/apps/search/facets.py new file mode 100644 index 0000000..25bbbdf --- /dev/null +++ b/apps/search/facets.py @@ -0,0 +1,18 @@ +from oscar.apps.search.facets import * + + +def base_sqs(): + """ + Return the base SearchQuerySet for Haystack searches. + """ + sqs = SearchQuerySet() + for facet in settings.OSCAR_SEARCH_FACETS["fields"].values(): + options = facet.get("options", {}) + sqs = sqs.facet(facet["field"], **options) + for facet in settings.OSCAR_SEARCH_FACETS["queries"].values(): + for query in facet["queries"]: + sqs = sqs.query_facet(facet["field"], query[1]) + + sqs = sqs.all() + return sqs + diff --git a/apps/search/search_indexes.py b/apps/search/search_indexes.py new file mode 100644 index 0000000..f521042 --- /dev/null +++ b/apps/search/search_indexes.py @@ -0,0 +1,111 @@ +from haystack import indexes + +from oscar.core.loading import get_class, get_model + +# Load default strategy (without a user/request) +is_solr_supported = get_class("search.features", "is_solr_supported") +Selector = get_class("partner.strategy", "Selector") + + +class ProductIndex(indexes.SearchIndex, indexes.Indexable): + # Search text + text = indexes.CharField( + document=True, + use_template=True, + template_name="oscar/search/indexes/product/item_text.txt", + ) + + upc = indexes.CharField(model_attr="upc", null=True) + title = indexes.EdgeNgramField(model_attr="title", null=True) + title_exact = indexes.CharField(model_attr="title", null=True, indexed=False) + + # Fields for faceting + product_class = indexes.CharField(null=True, faceted=False) + category = indexes.MultiValueField(null=True, faceted=True) + price = indexes.FloatField(null=True, faceted=True) + num_in_stock = indexes.IntegerField(null=True, faceted=True) + rating = indexes.IntegerField(null=True, faceted=True) + + # Spelling suggestions + suggestions = indexes.FacetCharField() + + date_created = indexes.DateTimeField(model_attr="date_created") + date_updated = indexes.DateTimeField(model_attr="date_updated") + + is_public = indexes.BooleanField(model_attr="is_public") + structure = indexes.CharField(model_attr="structure") + + _strategy = None + + def get_model(self): + return get_model("catalogue", "Product") + + def index_queryset(self, using=None): + # Only index browsable products (not each individual child product) + return self.get_model().objects.browsable().order_by("-date_updated") + + def read_queryset(self, using=None): + return self.get_model().objects.browsable().base_queryset() + + def prepare_product_class(self, obj): + return obj.get_product_class().name + + def prepare_category(self, obj): + return list(obj.get_categories().values_list("pk", flat=True)) or [] + + def prepare_rating(self, obj): + if obj.rating is not None: + return int(obj.rating) + + # Pricing and stock is tricky as it can vary per customer. However, the + # most common case is for customers to see the same prices and stock levels + # and so we implement that case here. + + def get_strategy(self): + if not self._strategy: + self._strategy = Selector().strategy() + return self._strategy + + def prepare_price(self, obj): + strategy = self.get_strategy() + result = None + if obj.is_parent: + result = strategy.fetch_for_parent(obj) + elif obj.has_stockrecords: + result = strategy.fetch_for_product(obj) + + if result: + if result.price.is_tax_known: + return result.price.incl_tax + return result.price.excl_tax + + def prepare_num_in_stock(self, obj): + strategy = self.get_strategy() + if obj.is_parent: + # Don't return a stock level for parent products + return None + elif obj.has_stockrecords: + result = strategy.fetch_for_product(obj) + return result.stockrecord.net_stock_level + + def prepare(self, obj): + prepared_data = super().prepare(obj) + + # We use Haystack's dynamic fields to ensure that the title field used + # for sorting is of type "string'. + if is_solr_supported(): + prepared_data["title_s"] = prepared_data["title"] + + # Use title for spelling suggestions + prepared_data["suggestions"] = prepared_data["title"] + + return prepared_data + + def get_updated_field(self): + """ + Used to specify the field used to determine if an object has been + updated + + Can be used to filter the query set when updating the index + """ + return "date_updated" diff --git a/e_store_primzel/settings/base.py b/e_store_primzel/settings/base.py index 8e56aec..3f8a862 100644 --- a/e_store_primzel/settings/base.py +++ b/e_store_primzel/settings/base.py @@ -100,33 +100,8 @@ # Search facets OSCAR_SEARCH_FACETS = { "fields": { - # The key for these dicts will be used when passing facet data - # to the template. Same for the 'queries' dict below. - "product_class": {"name": _("Type"), "field": "product_class"}, - "rating": {"name": _("Rating"), "field": "rating"}, - # You can specify an 'options' element that will be passed to the - # SearchQuerySet.facet() call. - # For instance, with Elasticsearch backend, 'options': {'order': 'term'} - # will sort items in a facet by title instead of number of items. - # It's hard to get 'missing' to work - # correctly though as of Solr's hilarious syntax for selecting - # items without a specific facet: - # http://wiki.apache.org/solr/SimpleFacetParameters#facet.method - # 'options': {'missing': 'true'} }, "queries": { - "price_range": { - "name": _("Price range"), - "field": "price", - "queries": [ - # This is a list of (name, query) tuples where the name will - # be displayed on the front-end. - (_("0 to 20"), "[0 TO 20]"), - (_("20 to 40"), "[20 TO 40]"), - (_("40 to 60"), "[40 TO 60]"), - (_("60+"), "[60 TO *]"), - ], - }, }, } OSCAR_DASHBOARD_NAVIGATION += [ diff --git a/e_store_primzel/settings/install_apps.py b/e_store_primzel/settings/install_apps.py index 5d52d9d..293dcc1 100644 --- a/e_store_primzel/settings/install_apps.py +++ b/e_store_primzel/settings/install_apps.py @@ -16,7 +16,7 @@ 'oscar.apps.basket.apps.BasketConfig', 'oscar.apps.offer.apps.OfferConfig', 'oscar.apps.order.apps.OrderConfig', - 'oscar.apps.search.apps.SearchConfig', + 'apps.search.apps.SearchConfig', 'oscar.apps.voucher.apps.VoucherConfig', 'oscar.apps.wishlists.apps.WishlistsConfig', 'apps.dashboard.apps.DashboardConfig', From 13b9e71dc91b8258b425e5e83c010dbbc277baaa Mon Sep 17 00:00:00 2001 From: qasim Date: Thu, 18 Sep 2025 20:00:06 +0500 Subject: [PATCH 4/8] fix: broken templates --- templates/eggs/templates/oscar/catalogue/browse.html | 4 ++-- templates/localhost_db/templates/oscar/catalogue/browse.html | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/eggs/templates/oscar/catalogue/browse.html b/templates/eggs/templates/oscar/catalogue/browse.html index 5cf42a6..7fdc0df 100644 --- a/templates/eggs/templates/oscar/catalogue/browse.html +++ b/templates/eggs/templates/oscar/catalogue/browse.html @@ -36,7 +36,7 @@ {% for product in products %}
- {% render_product product %} + {% render_product product.object %}
{% endfor %} @@ -79,4 +79,4 @@
Added to cart!
-{% endblock %} \ No newline at end of file +{% endblock %} diff --git a/templates/localhost_db/templates/oscar/catalogue/browse.html b/templates/localhost_db/templates/oscar/catalogue/browse.html index 0f7749e..2756c4f 100644 --- a/templates/localhost_db/templates/oscar/catalogue/browse.html +++ b/templates/localhost_db/templates/oscar/catalogue/browse.html @@ -60,7 +60,7 @@
    {% for product in products %} -
  1. {% render_product product %}
  2. +
  3. {% render_product product.object %}
  4. {% endfor %}
{% include "oscar/partials/pagination.html" %} From 3cc01680543d52e04b066d6dfbdd7a61497cca40 Mon Sep 17 00:00:00 2001 From: qasim Date: Thu, 18 Sep 2025 20:04:41 +0500 Subject: [PATCH 5/8] fix: broken action --- e_store_primzel/urls.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/e_store_primzel/urls.py b/e_store_primzel/urls.py index ec061e8..ec6dcd7 100644 --- a/e_store_primzel/urls.py +++ b/e_store_primzel/urls.py @@ -13,7 +13,6 @@ 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ -from debug_toolbar.toolbar import debug_toolbar_urls from django.apps import apps from django.conf import settings from django.contrib import admin @@ -40,6 +39,6 @@ urlpatterns += staticfiles_urlpatterns() if settings.DEBUG: - from django.urls import path + from debug_toolbar.toolbar import debug_toolbar_urls urlpatterns = debug_toolbar_urls() + urlpatterns From 64cbaa397e3ef4f192be3004b9bcfa78a80a4351 Mon Sep 17 00:00:00 2001 From: qasim Date: Thu, 18 Sep 2025 20:06:58 +0500 Subject: [PATCH 6/8] fix: broken action --- .github/workflows/migrations-checker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/migrations-checker.yml b/.github/workflows/migrations-checker.yml index 1060358..67e6b51 100644 --- a/.github/workflows/migrations-checker.yml +++ b/.github/workflows/migrations-checker.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest services: postgres: - image: kiasaki/alpine-postgres:9.5 + image: bitnami/postgresql:latest env: POSTGRES_USER: primzel_store POSTGRES_PASSWORD: primzel_store From af1c1b9851406998b2b15c66ffe51c930461a52c Mon Sep 17 00:00:00 2001 From: qasim Date: Thu, 18 Sep 2025 20:10:21 +0500 Subject: [PATCH 7/8] fix: broken action --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index bc98840..244a87b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,7 +43,7 @@ services: - redis.oscar.com postgres: restart: always - image: bitnami/postgresql:latest + image: postgres:17 container_name: com.primzel.psql hostname: psql.primzel.com environment: From a138799050729505aafd0471ed42a4158109e7e4 Mon Sep 17 00:00:00 2001 From: qasim Date: Thu, 18 Sep 2025 20:11:16 +0500 Subject: [PATCH 8/8] fix: broken action --- .github/workflows/migrations-checker.yml | 2 +- docker-compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/migrations-checker.yml b/.github/workflows/migrations-checker.yml index 67e6b51..f5771cd 100644 --- a/.github/workflows/migrations-checker.yml +++ b/.github/workflows/migrations-checker.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest services: postgres: - image: bitnami/postgresql:latest + image: postgres:17 env: POSTGRES_USER: primzel_store POSTGRES_PASSWORD: primzel_store diff --git a/docker-compose.yml b/docker-compose.yml index 244a87b..bc98840 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -43,7 +43,7 @@ services: - redis.oscar.com postgres: restart: always - image: postgres:17 + image: bitnami/postgresql:latest container_name: com.primzel.psql hostname: psql.primzel.com environment: