mirror of
https://github.com/Hopiu/wagtail.git
synced 2026-03-16 22:10:28 +00:00
parent
233e7f5189
commit
4001516a27
7 changed files with 139 additions and 2 deletions
|
|
@ -18,6 +18,7 @@ Changelog
|
|||
* Add StreamFieldPanel to available panel types in documentation (Dan Swain)
|
||||
* Add {{ block.super }} example to ModelAdmin customisation in documentation (Dan Swain)
|
||||
* Add ability to filter image index by a tag (Benedikt Willi)
|
||||
* Add formal support for nested InlinePanels (Matt Westcott)
|
||||
* Fix: Rename documents listing column 'uploaded' to 'created' (LB (Ben Johnston))
|
||||
* Fix: Submenu items longer then the page height are no longer broken by the submenu footer (Igor van Spengen)
|
||||
* Fix: Unbundle the l18n library as it was bundled to avoid installation errors which have been resolved (Matt Westcott)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ Other features
|
|||
* Add StreamFieldPanel to available panel types in documentation (Dan Swain)
|
||||
* Add {{ block.super }} example to ModelAdmin customisation in documentation (Dan Swain)
|
||||
* Add ability to filter image index by a tag (Benedikt Willi)
|
||||
* Add formal support for nested InlinePanels (Matt Westcott)
|
||||
|
||||
|
||||
Bug fixes
|
||||
|
|
|
|||
|
|
@ -66,6 +66,10 @@ class WagtailAdminModelFormMetaclass(ClusterFormMetaclass):
|
|||
new_class = super(WagtailAdminModelFormMetaclass, cls).__new__(cls, name, bases, attrs)
|
||||
return new_class
|
||||
|
||||
@classmethod
|
||||
def child_form(cls):
|
||||
return WagtailAdminModelForm
|
||||
|
||||
|
||||
class WagtailAdminModelForm(ClusterForm, metaclass=WagtailAdminModelFormMetaclass):
|
||||
@property
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ from wagtail.tests.testapp.models import (
|
|||
EVENT_AUDIENCE_CHOICES, Advert, AdvertPlacement, EventCategory,
|
||||
EventPage, EventPageCarouselItem, FilePage, ManyToManyBlogPage, SimplePage, SingleEventPage, StandardIndex, TaggedPage)
|
||||
from wagtail.tests.utils import WagtailTestUtils
|
||||
from wagtail.tests.utils.form_data import inline_formset, nested_form_data
|
||||
|
||||
|
||||
class TestPageEdit(TestCase, WagtailTestUtils):
|
||||
|
|
@ -1632,3 +1633,92 @@ class TestValidationErrorMessages(TestCase, WagtailTestUtils):
|
|||
self.assertContains(response, """<p class="error-message"><span>This field is required.</span></p>""", count=1, html=True)
|
||||
# Error on title shown in the header message
|
||||
self.assertContains(response, "<li>Title: This field is required.</li>", count=1)
|
||||
|
||||
|
||||
class TestNestedInlinePanel(TestCase, WagtailTestUtils):
|
||||
fixtures = ['test.json']
|
||||
|
||||
def setUp(self):
|
||||
self.events_index = Page.objects.get(url_path='/home/events/')
|
||||
self.christmas_page = EventPage.objects.get(url_path='/home/events/christmas/')
|
||||
self.speaker = self.christmas_page.speakers.first()
|
||||
self.speaker.awards.create(
|
||||
name="Beard Of The Year", date_awarded=datetime.date(1997, 12, 25)
|
||||
)
|
||||
self.speaker.save()
|
||||
self.user = self.login()
|
||||
|
||||
def test_get_edit_form(self):
|
||||
response = self.client.get(
|
||||
reverse('wagtailadmin_pages:edit', args=(self.christmas_page.id, ))
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(
|
||||
response,
|
||||
"""<input type="text" name="speakers-0-awards-0-name" value="Beard Of The Year" maxlength="255" id="id_speakers-0-awards-0-name">""",
|
||||
count=1, html=True
|
||||
)
|
||||
|
||||
# there should be no "extra" forms, as the nested formset should respect the extra_form_count=0 set on WagtailAdminModelForm
|
||||
self.assertContains(
|
||||
response,
|
||||
"""<input type="hidden" name="speakers-0-awards-TOTAL_FORMS" value="1" id="id_speakers-0-awards-TOTAL_FORMS">""",
|
||||
count=1, html=True
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
"""<input type="text" name="speakers-0-awards-1-name" value="" maxlength="255" id="id_speakers-0-awards-1-name">""",
|
||||
count=0, html=True
|
||||
)
|
||||
|
||||
# date field should use AdminDatePicker
|
||||
self.assertContains(
|
||||
response,
|
||||
"""<input type="text" name="speakers-0-awards-0-date_awarded" value="1997-12-25" autocomplete="new-date" id="id_speakers-0-awards-0-date_awarded">""",
|
||||
count=1, html=True
|
||||
)
|
||||
|
||||
def test_post_edit(self):
|
||||
post_data = nested_form_data({
|
||||
'title': "Christmas",
|
||||
'date_from': "2017-12-25",
|
||||
'date_to': "2017-12-25",
|
||||
'slug': "christmas",
|
||||
'audience': "public",
|
||||
'location': "The North Pole",
|
||||
'cost': "Free",
|
||||
'carousel_items': inline_formset([]),
|
||||
'speakers': inline_formset([
|
||||
{
|
||||
'id': self.speaker.id,
|
||||
'first_name': "Jeff",
|
||||
'last_name': "Christmas",
|
||||
'awards': inline_formset([
|
||||
{
|
||||
'id': self.speaker.awards.first().id,
|
||||
'name': "Beard Of The Century",
|
||||
'date_awarded': "1997-12-25",
|
||||
},
|
||||
{
|
||||
'name': "Bobsleigh Olympic gold medallist",
|
||||
'date_awarded': "2018-02-01",
|
||||
},
|
||||
], initial=1)
|
||||
},
|
||||
], initial=1),
|
||||
'related_links': inline_formset([]),
|
||||
'head_counts': inline_formset([]),
|
||||
'action-publish': "Publish",
|
||||
})
|
||||
response = self.client.post(
|
||||
reverse('wagtailadmin_pages:edit', args=(self.christmas_page.id, )),
|
||||
post_data
|
||||
)
|
||||
self.assertRedirects(response, reverse('wagtailadmin_explore', args=(self.events_index.id, )))
|
||||
|
||||
new_christmas_page = EventPage.objects.get(url_path='/home/events/christmas/')
|
||||
self.assertEqual(new_christmas_page.speakers.first().first_name, "Jeff")
|
||||
awards = new_christmas_page.speakers.first().awards.all()
|
||||
self.assertEqual(len(awards), 2)
|
||||
self.assertEqual(awards[0].name, "Beard Of The Century")
|
||||
self.assertEqual(awards[1].name, "Bobsleigh Olympic gold medallist")
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ class TestExtractPanelDefinitionsFromModelClass(TestCase):
|
|||
def test_can_extract_panel_property(self):
|
||||
# A class with a 'panels' property defined should return that list
|
||||
result = extract_panel_definitions_from_model_class(EventPageSpeaker)
|
||||
self.assertEqual(len(result), 4)
|
||||
self.assertEqual(len(result), 5)
|
||||
self.assertTrue(any([isinstance(panel, ImageChooserPanel) for panel in result]))
|
||||
|
||||
def test_exclude(self):
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
# Generated by Django 2.1.11 on 2019-09-06 15:11
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
import modelcluster.fields
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('tests', '0042_simplechildpage_simpleparentpage'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='EventPageSpeakerAward',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
|
||||
('name', models.CharField(max_length=255, verbose_name='Award name')),
|
||||
('date_awarded', models.DateField(blank=True, null=True)),
|
||||
('speaker', modelcluster.fields.ParentalKey(on_delete=django.db.models.deletion.CASCADE, related_name='awards', to='tests.EventPageSpeaker')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['sort_order'],
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
]
|
||||
|
|
@ -198,7 +198,18 @@ class EventPageRelatedLink(Orderable, RelatedLink):
|
|||
page = ParentalKey('tests.EventPage', related_name='related_links', on_delete=models.CASCADE)
|
||||
|
||||
|
||||
class EventPageSpeaker(Orderable, LinkFields):
|
||||
class EventPageSpeakerAward(Orderable, models.Model):
|
||||
speaker = ParentalKey('tests.EventPageSpeaker', related_name='awards', on_delete=models.CASCADE)
|
||||
name = models.CharField("Award name", max_length=255)
|
||||
date_awarded = models.DateField(null=True, blank=True)
|
||||
|
||||
panels = [
|
||||
FieldPanel('name'),
|
||||
FieldPanel('date_awarded'),
|
||||
]
|
||||
|
||||
|
||||
class EventPageSpeaker(Orderable, LinkFields, ClusterableModel):
|
||||
page = ParentalKey('tests.EventPage', related_name='speakers', related_query_name='speaker', on_delete=models.CASCADE)
|
||||
first_name = models.CharField("Name", max_length=255, blank=True)
|
||||
last_name = models.CharField("Surname", max_length=255, blank=True)
|
||||
|
|
@ -219,6 +230,7 @@ class EventPageSpeaker(Orderable, LinkFields):
|
|||
FieldPanel('last_name'),
|
||||
ImageChooserPanel('image'),
|
||||
MultiFieldPanel(LinkFields.panels, "Link"),
|
||||
InlinePanel('awards', label="Awards"),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue