diff --git a/combo/apps/wcs/forms.py b/combo/apps/wcs/forms.py index 79172e4e..9b031422 100644 --- a/combo/apps/wcs/forms.py +++ b/combo/apps/wcs/forms.py @@ -77,7 +77,7 @@ class WcsCardInfoCellForm(forms.ModelForm): with_user = forms.BooleanField( label=_('Restrict to cards accessible to the user'), required=False, initial=True ) - related_card_path = forms.ChoiceField(label=_('Card Identifier'), required=False) + related_card_path = forms.ChoiceField(label=_('Card(s) to display'), required=False) class Meta: model = WcsCardInfosCell diff --git a/combo/apps/wcs/migrations/0051_new_card_cell.py b/combo/apps/wcs/migrations/0051_new_card_cell.py new file mode 100644 index 00000000..2a969c07 --- /dev/null +++ b/combo/apps/wcs/migrations/0051_new_card_cell.py @@ -0,0 +1,108 @@ +import django.contrib.postgres.fields.jsonb +import django.db.models.deletion +from django.db import migrations, models + +import combo.apps.wcs.models + + +class Migration(migrations.Migration): + + dependencies = [ + ('auth', '0011_update_proxy_permissions'), + ('data', '0057_pagesnapshot_label'), + ('wcs', '0050_card_display_mode'), + ] + + operations = [ + migrations.CreateModel( + name='WcsCardCell', + fields=[ + ( + 'id', + models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID'), + ), + ('placeholder', models.CharField(max_length=20)), + ('order', models.PositiveIntegerField()), + ('slug', models.SlugField(blank=True, verbose_name='Slug')), + ( + 'extra_css_class', + models.CharField( + blank=True, max_length=100, verbose_name='Extra classes for CSS styling' + ), + ), + ( + 'template_name', + models.CharField(blank=True, max_length=50, null=True, verbose_name='Cell Template'), + ), + ( + 'condition', + models.CharField( + blank=True, max_length=1000, null=True, verbose_name='Display condition' + ), + ), + ('public', models.BooleanField(default=True, verbose_name='Public')), + ( + 'restricted_to_unlogged', + models.BooleanField(default=False, verbose_name='Restrict to unlogged users'), + ), + ('last_update_timestamp', models.DateTimeField(auto_now=True)), + ('carddef_reference', models.CharField(max_length=150, verbose_name='Card Model')), + ( + 'related_card_path', + models.CharField(blank=True, max_length=1000, verbose_name='Card(s) to display'), + ), + ( + 'card_ids', + models.CharField(blank=True, max_length=1000, verbose_name='Other Card Identifiers'), + ), + ( + 'only_for_user', + models.BooleanField( + default=False, verbose_name='Limit to cards linked to the logged-in user' + ), + ), + ( + 'without_user', + models.BooleanField(default=False, verbose_name='Ignore the logged-in user'), + ), + ( + 'limit', + models.PositiveSmallIntegerField( + blank=True, null=True, verbose_name='Number of cards per page (default 10)' + ), + ), + ('custom_schema', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)), + ( + 'display_mode', + models.CharField( + choices=[('card', 'Card'), ('table', 'Table')], + default='card', + max_length=10, + verbose_name='Display mode', + ), + ), + ( + 'title_type', + models.CharField( + choices=[ + ('auto', 'Default Title (Card Label)'), + ('manual', 'Custom Title'), + ('empty', 'No Title'), + ], + default='auto', + max_length=20, + verbose_name='Title', + ), + ), + ('custom_title', models.CharField(blank=True, max_length=150, verbose_name='Custom Title')), + ('cached_title', models.CharField(max_length=150, verbose_name='Title')), + ('cached_json', django.contrib.postgres.fields.jsonb.JSONField(blank=True, default=dict)), + ('groups', models.ManyToManyField(blank=True, to='auth.Group', verbose_name='Groups')), + ('page', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='data.Page')), + ], + options={ + 'verbose_name': 'Card(s)', + }, + bases=(combo.apps.wcs.models.CardMixin, models.Model), + ), + ] diff --git a/combo/apps/wcs/models.py b/combo/apps/wcs/models.py index 8c0368c8..28344d7d 100644 --- a/combo/apps/wcs/models.py +++ b/combo/apps/wcs/models.py @@ -940,6 +940,47 @@ class WcsCardsCell(CardMixin, WcsBlurpMixin, CellBase): return '' +@register_cell_class +class WcsCardCell(CardMixin, CellBase): + carddef_reference = models.CharField(_('Card Model'), max_length=150) + related_card_path = models.CharField(_('Card(s) to display'), max_length=1000, blank=True) + card_ids = models.CharField(_('Other Card Identifiers'), max_length=1000, blank=True) + only_for_user = models.BooleanField(_('Limit to cards linked to the logged-in user'), default=False) + without_user = models.BooleanField(_('Ignore the logged-in user'), default=False) + limit = models.PositiveSmallIntegerField( + _('Number of cards per page (default 10)'), null=True, blank=True + ) + custom_schema = JSONField(blank=True, default=dict) + display_mode = models.CharField( + _('Display mode'), + max_length=10, + default='card', + choices=[ + ('card', _('Card')), + ('table', _('Table')), + ], + ) + + title_type = models.CharField( + _('Title'), + max_length=20, + default='auto', + blank=False, + choices=[ + ('auto', _('Default Title (Card Label)')), + ('manual', _('Custom Title')), + ('empty', _('No Title')), + ], + ) + custom_title = models.CharField(_('Custom Title'), max_length=150, blank=True) + + cached_title = models.CharField(_('Title'), max_length=150) + cached_json = JSONField(blank=True, default=dict) + + class Meta: + verbose_name = _('Card(s)') + + @register_cell_class class WcsCardInfosCell(CardMixin, CellBase): carddef_reference = models.CharField(_('Card Model'), max_length=150) diff --git a/tests/test_manager.py b/tests/test_manager.py index df9699ee..20aec8b6 100644 --- a/tests/test_manager.py +++ b/tests/test_manager.py @@ -1040,7 +1040,7 @@ def test_site_export_import_json(app, admin_user): resp.form['site_file'] = Upload('site-export.json', site_export, 'application/json') with CaptureQueriesContext(connection) as ctx: resp = resp.form.submit() - assert len(ctx.captured_queries) in [309, 310] + assert len(ctx.captured_queries) in [314, 315] assert Page.objects.count() == 4 assert PageSnapshot.objects.all().count() == 4 @@ -1051,7 +1051,7 @@ def test_site_export_import_json(app, admin_user): resp.form['site_file'] = Upload('site-export.json', site_export, 'application/json') with CaptureQueriesContext(connection) as ctx: resp = resp.form.submit() - assert len(ctx.captured_queries) == 278 + assert len(ctx.captured_queries) == 282 assert set(Page.objects.get(slug='one').related_cells['cell_types']) == {'data_textcell', 'data_linkcell'} assert Page.objects.count() == 4 assert LinkCell.objects.count() == 2 @@ -2447,7 +2447,7 @@ def test_page_versionning(app, admin_user): with CaptureQueriesContext(connection) as ctx: resp2 = resp.click('view', index=1) - assert len(ctx.captured_queries) == 71 + assert len(ctx.captured_queries) == 72 assert Page.snapshots.latest('pk').related_cells == {'cell_types': ['data_textcell']} assert resp2.text.index('Hello world') < resp2.text.index('Foobar3') @@ -2508,7 +2508,7 @@ def test_page_versionning(app, admin_user): resp = resp.click('restore', index=6) with CaptureQueriesContext(connection) as ctx: resp = resp.form.submit().follow() - assert len(ctx.captured_queries) == 155 + assert len(ctx.captured_queries) == 157 resp2 = resp.click('See online') assert resp2.text.index('Foobar1') < resp2.text.index('Foobar2') < resp2.text.index('Foobar3') diff --git a/tests/test_search.py b/tests/test_search.py index 164cbcf9..bcd1cc5e 100644 --- a/tests/test_search.py +++ b/tests/test_search.py @@ -1432,7 +1432,7 @@ def test_index_site_num_queries(settings, app): assert IndexedCell.objects.count() == 50 with CaptureQueriesContext(connection) as ctx: index_site() - assert len(ctx.captured_queries) in (175, 225) # (3.2, 2.2) + assert len(ctx.captured_queries) in (176, 226) # (3.2, 2.2) SearchCell.objects.create( page=page, placeholder='content', order=0, _search_services={'data': ['search1']}