MultiFieldPanel width in Wagtail and displayed name - python

I have the following MultiFieldPanel.
class TeamRooster(Page):
staff = StreamField([
('staff', CardsBlock(Staff(), icon="plus")),
], blank=True)
content_panels = [
MultiFieldPanel(
[ StreamFieldPanel('staff') ],
heading="Staff", classname="col12"
),
three times "Staff" is too much. I looked in the documentation and tried to delete the names but I have a bug.
And how to change the width of MultiFieldPanel? I tried to add classname="full" but it doesn't help me.

As #lb-ben-johnston said I changed content_panels []
Thanks #lb-ben-johnston!

Related

Value Error: Field 'id' expected a number but got 'create'

I was in the process of making a create gallery image field in Django for my project, but when I try to access the url, I'm getting a Field 'id' expected a number but got 'create'. error. And on postman, I'm getting a { detail: "Method \"POST\" not allowed." }.
class Gallery(models.Model):
SUBTLEPBR = "subtle"
AMULET = "amulet"
F8THFULPBR = "f8thfulpbr"
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
screenshot_by = models.CharField(max_length=200, null=False, blank=False)
image = WEBPField(
verbose_name=('Image'),
upload_to=image_folder,
default="placeholder.png"
)
PACKS = [
(SUBTLEPBR, 'SubtlePBR'),
(AMULET, 'Amulet'),
(F8THFULPBR, 'F8thfulPBR'),
]
pack = models.CharField(max_length=10, choices=PACKS)
def __str__(self):
return "Screenshot by "+ self.screenshot_by + " | " + self.pack
#api_view(["POST"])
#permission_classes([IsAdminUser])
def createGalleryImage(request):
user = request.user
gallery = Gallery.objects.create(
user = user,
screenshot_by = "John Doe",
pack = Gallery.SUBTLEPBR,
)
serializer = GallerySerializer(gallery, many=False)
return Response(serializer.data)
urlpatterns = [
path('admin/users/login/', views.MyTokenObtainPairView.as_view(), name='token_obtain_pair'),
path('', views.getRoutes, name='routes'),
path("gallery/", views.GalleryImages, name="gallery"),
path("gallery/<str:pk>/", views.getGalleryImage, name="gallery-image"),
path("gallery/delete/<str:pk>/", views.deleteGalleryImage, name="gallery-delete"),
path("gallery/create/", views.createGalleryImage, name="gallery-create"),
path("updates/", views.PackUpdatesPage, name="updates"),
path("faq/", views.FaqPage, name="faq"),
path("subtle-roadmap/", views.SubtleRoadmapPage, name="subtle-roadmap"),
path("amulet-roadmap/", views.AmuletRoadmapPage, name="amulet-roadmap"),
path('admin/users/profile/', views.getUserProfile, name="user-profile")
]
The output that is supposed to happen is
{
"id": 51,
"screenshot_by": "Person",
"image": "/placeholder.png",
"pack": "subtle",
"user": 1
}
(added entire urls code to include entirety of paths)
This will "fire" the wrong view. Indeed, if you use /gallery/create, it will fire getGalleryImage with create as pk.
If the primary keys are integers, you can restrict these with:
urlpatterns = [
path('gallery/<int:pk>/', views.getGalleryImage, name='gallery-image'),
path(
'gallery/delete/<int:pk>/',
views.deleteGalleryImage,
name='gallery-delete',
),
path('gallery/create/', views.createGalleryImage, name='gallery-create'),
# …
]
This will then only "fire" if pk is a sequence of digits, like 1425, not create.

Wagtail | ChoiceField not displayed

I am facing some kind of incomprehensible behavior working with "StructBlock" and "ChoiceBlock". For some reasons the ChoiceBlock dont show up in admin-menu if designed via class-notation.
Like that no choiceblock is shown at admin-menu. Only the textblock.
class CodeBlock(blocks.StructBlock):
code = blocks.TextBlock(required=True)
type = blocks.ChoiceBlock(choices=[
('markup', 'markup'), ('css', 'css')
], required=True),
class Meta:
template = 'home/blocks/code.html'
class HomePageIndex(Page):
body = StreamField([('code', CodeBlock())])
content_panels = Page.content_panels + [
StreamFieldPanel('body'),
]
The following solution is in my opinion pretty much equal, but works well. I do not get why... Due the fact i need the Struct-Field more often i prefer the the class-notation.
class HomePageIndex(Page):
body = StreamField([
('code', blocks.StructBlock([
('code', blocks.TextBlock(required=True)),
('type', blocks.ChoiceBlock(choices=[
('markup', 'markup'), ('css', 'css')
], template='home/blocks/code.html'))
])
content_panels = Page.content_panels + [
StreamFieldPanel('body'),
Not get me wrong, i could make it work (using the bad-way). I wonder why that happens.
Ty in advance

Wagtail - Possible to rename an item in a streamfield in a migration?

I've changed the name of an item in a StreamField from
tiles = StreamField(
[
('items', StructBlock([
('icon', ImageChooserBlock()),
('text', CharBlock()),
])
),
], blank=True)
To
tiles = StreamField(
[
('info', StructBlock([
('icon', ImageChooserBlock()),
('text', CharBlock()),
])
),
], blank=True)
Any idea how I can create a migration to rename the field ?
Streamfield data is stored as JSON, as a list of items with 'type' and 'value' properties. To apply the field name change to all of your pages, you should be able to create an empty migration (or add it to an existing one), then add the following function or something similar to your migration file, then run it:
// other imports
import json
def convert_streamfield_name(apps, schema_editor):
db_alias = schema_editor.connection.alias
MyPageModel = apps.get_model('myapp', 'MyPageModel')
pages = MyPageModel.objects.using(db_alias).all()
for page in pages:
revised_stream_data = []
stream_data = page.tiles.stream_data
for data in stream_data:
if data.get('type') == 'items':
value = data.get('value')
revised_stream_data.append({
'type': 'info'
'value': value
})
else:
revised_stream_data.append(data)
raw_json = json.dumps(revised_stream_data)
page.tiles = raw_json
page.save()
class Migration(migrations.Migration):
dependencies = [...]
operations = [
migrations.RunPython(convert_streamfield_name),
...
]

Wagtail admin ,CheckboxSelectMultiple not saving data

#register_snippet
class Numbers(models.Model):
number = models.IntegerField()
class State(models.Model):
state = models.CharField(max_length=100)
number = ParentalManyToManyField(Numbers)
class HomeStateNumber(State):
page = ParentalKey('home.HomePage', related_name='helpline')
api_fields = ['state', 'number']
panels = [
FieldPanel('state'),
FieldPanel('number',widget=forms.CheckboxSelectMultiple),
]
class HomePage(Page):
content_panels = [
FieldPanel('title'),
ImageChooserPanel('cover_page'),
InlinePanel('ticker', label="ticker"),
InlinePanel('helpline', label="helpline"),
]
I want to add one than more number in a state , wagtail shows correct order in admin , when you select number from multiple and save the page, data is not saved. It remains None (queryset)
Is there any other way to do this ?
I think i am doing wrong somewhere
Please help
Models using ParentalManyToManyField need to inherit from modelcluster.models.ClusterableModel.
from modelcluster.models import ClusterableModel
class State(ClusterableModel):
state = models.CharField(max_length=100)
number = ParentalManyToManyField(Numbers)
Also, make sure you have django-modelcluster version 4.0 (or above) installed - older versions had a bug preventing m2m relations in inline objects from working.

How can I add a document on a StreamField in Wagtail CMS?

I've a question about Wagtail CMS.
Recently I'm trying to import programmatically some documents in a StreamField of an instance of a Wagtail Page model. I've done some researches but without results.
Currently I'm using:
Wagtail 1.13
Django 1.11.6
Python 2.7
Here the model of the page in which I need to import the documents as attachments (see the homonym field):
class EventPage(TranslatablePage, Page):
# Database fields
uuid = models.UUIDField(verbose_name='UUID', default=uuid.uuid4)
start_date = models.DateField(verbose_name='Start date')
end_date = models.DateField(verbose_name='End date')
location = models.CharField(verbose_name='Place', max_length=255, null=True, blank=True)
body = RichTextField(verbose_name='Body')
attachments = StreamField(blocks.StreamBlock([
('document', DocumentChooserBlock(label='Document', icon='doc-full-inverse')),
]), verbose_name='Attachments', null=True, blank=True)
subscribe = models.BooleanField(verbose_name='Subscribe option', default=False)
# Editor panels configuration
content_panels = [
FieldPanel('title', classname='title'),
MultiFieldPanel([
FieldRowPanel([
FieldPanel('start_date'),
FieldPanel('end_date'),
]),
], heading='Period'),
FieldPanel('location'),
FieldPanel('body'),
StreamFieldPanel('attachments'),
]
promote_panels = Page.promote_panels + [
MultiFieldPanel([
FieldPanel('subscribe'),
], heading='Custom Settings'),
]
settings_panels = TranslatablePage.settings_panels + [
MultiFieldPanel([
FieldPanel('uuid'),
], heading='Meta')
]
parent_page_types = ["home.FolderPage"]
subpage_types = []
On shell, I tried to apply the solution explained on this page but without success.
event = EventPage.objects.get(pk=20)
doc = Document.objects.get(pk=3)
event.attachments = [
('document',
[
StreamValue.StreamChild(
id = None,
block = DocumentChooserBlock(),
value = doc
)
]
)
]
Python give me this error: AttributeError: 'list' object has no attribute 'pk'.
event.attachments = [('document', doc)] should work, I believe. (On the other question you link to, StreamChild was necessary because AccordionRepeaterBlock was a StreamBlock nested in a StreamBlock; that's not the case for your definition.)
To add a document to the existing StreamField content, build a new list and assign that to event.attachments:
new_attachments = [(block.block_type, block.value) for block in blocks]
new_attachments.append(('document', doc))
event.attachments = new_attachments
(Currently you can't append directly to a StreamField value, but this may well be supported in a future Wagtail release...)

Categories

Resources