Python 在Wagtail中隐藏“***块”

Python 在Wagtail中隐藏“***块”,python,django,wagtail,Python,Django,Wagtail,在Wagtail中,我用ImageChooserBlock制作了一个块,如下所示: class MyBlock(blocks.StructBlock): background = ImageChooserBlock() class FancyImageChooserBlock(ImageChooserBlock): extra = blocks.Charfield() class MyBlock(blocks.StructBlock): background = Fa

在Wagtail中,我用
ImageChooserBlock
制作了一个块,如下所示:

class MyBlock(blocks.StructBlock):
    background = ImageChooserBlock()
class FancyImageChooserBlock(ImageChooserBlock):
    extra = blocks.Charfield()

class MyBlock(blocks.StructBlock):
    background = FancyImageChooserBlock()
class ImageModel(AbstractImage):
    extra = models.CharField(max_length=255, blank=True, null=True)

    admin_form_fields = Image.admin_form_fields # So that in the image edit page, the fields are shown

    def save(self, **kwargs):
        self.clean_extra()
        return super(ImageModel, self).save(**kwargs)

    def clean_extra(self):
        if something():
            extra = 'This gets added as an attribute of image'

# Needed for the rendition relation
class ImageRenditionModel(AbstractRendition):
    image = models.ForeignKey(ImageModel, related_name='renditions')

    class Meta:
        unique_together = (
            ('image', 'filter_spec', 'focal_point_key'),
        )
现在我想在
ImageChooserBlock
中添加一些额外的字段,所以我将其移动到了自己的块中,现在它看起来像这样:

class MyBlock(blocks.StructBlock):
    background = ImageChooserBlock()
class FancyImageChooserBlock(ImageChooserBlock):
    extra = blocks.Charfield()

class MyBlock(blocks.StructBlock):
    background = FancyImageChooserBlock()
class ImageModel(AbstractImage):
    extra = models.CharField(max_length=255, blank=True, null=True)

    admin_form_fields = Image.admin_form_fields # So that in the image edit page, the fields are shown

    def save(self, **kwargs):
        self.clean_extra()
        return super(ImageModel, self).save(**kwargs)

    def clean_extra(self):
        if something():
            extra = 'This gets added as an attribute of image'

# Needed for the rendition relation
class ImageRenditionModel(AbstractRendition):
    image = models.ForeignKey(ImageModel, related_name='renditions')

    class Meta:
        unique_together = (
            ('image', 'filter_spec', 'focal_point_key'),
        )
我的第一个问题是,
extra
字段没有包含在内。(可能是因为块继承自
ImageChooserBlock

我的第二个也是最重要的问题是,我希望能够在表单中隐藏额外的字段,但将其包含在模板呈现中。有人知道如何以及是否可能做到这一点吗?我不想为此做任何黑客行为。必须有一种方法使用
小部件
来做到这一点de>forms.HiddenInput或类似的东西

我知道我可以用我的
FancyImageChooserBlock
clean
方法进行一些计算,手动设置
extra
的值。这正是我想要做的


感谢您的帮助,我真的被困在这里。

关于您的第一个问题,为什么不:

class MyBlock(blocks.StructBlock):
    background = ImageChooserBlock()
    extra = blocks.Charfield()

?关于你的第一个问题,为什么不:

class MyBlock(blocks.StructBlock):
    background = ImageChooserBlock()
    extra = blocks.Charfield()

ImageBlockChooser与“StructBlock”或“ListBlock”或“StreamBlock”不同,它们都是为了“查找”您可能定义的任何子字段而设计的。只有结构块类型为“开箱即用”而准备。要使块使用字段,需要将其配置为使用/生成带有这些字段的模板。

就个人而言,我认为有更好的方法来实现您想要的,而不是将ImageChooser子类化,因为尝试并找到使用Wagtail提供的功能的方法通常会更加健壮,即使您必须对这些功能进行一些创新

但是,如果您仍然想知道如何通过子类化ImageChooser来完成(黑客攻击):

解决方案1-将ImageChooser子类化(这不是我的首选选项):

#选择器块类:
类MyImageChooserBlock(ImageChooserBlock):
@缓存的不动产
def小部件(自身):
从.mywidgetsfolder导入MyAdminImageChooser
返回MyAdminImageChooser
从wagtail.admin.widgets导入AdminChooser
从wagtail.images导入获取图像模型
#选择器管理类。。。
类MyAdminImageChooser(AdminChooser):
“”“此类与AdminImageChooser之间的唯一区别是
这一个提供了不同的模板值
在render_to_string方法中进行渲染,并添加某些
属性字典中的变量。您可能会逃之夭夭
通过子类化AdminImageChooser而不是AdminChooser
重写render_html方法,但出于某种原因
给我一个重复的“选择图像”按钮,它似乎没有
为了证明这一原则,必须对其进行修复
选择一个文本=(选择一个图像)
选择另一个文本=(更改图像)
链接到所选的文本('编辑此图像')
定义初始(自我,**kwargs):
超级()
self.image\u model=get\u image\u model()
def render_html(自身、名称、值、属性):
实例,value=self.get_实例和_id(self.image_模型,
价值)
属性['extra_hidden_fields']=('extra_1'、'extra_2')
原始\字段\ html=super()。呈现\ html(名称、值、属性)
返回render_to_string(“我的小部件文件夹/my_image\u chooser.html”{
“小部件”:自我,
“原始\u字段\u html”:原始\u字段\u html,
“属性”:属性,
“值”:值,
“图像”:实例,
})
def render_js_init(self、id、name、value):
返回“createImageChooser({0});”格式(json.dumps(id)))
#my widgets文件夹/my_image_chooser.html模板:
{%extends“wagtailadmin/widgets/chooser.html”%}
{%load WAGTAIMAGES_tags%}
{%block chooser_class%}图像选择器{%endblock%}
{%block selected\u state\u view%}
{attrs.extra_hidden_fields%}
{%endfor%}
{%if图像%}
{%image max-300x300 class=“显示透明度”%}
{%else%}
{%endif%}
{%endblock%}
{%block edit_selected_item_url%}{%if image%}{%url'wagtailimages:edit'image.id%}{%endif%}{%endblock%}
解决方案2-使用自定义结构块和组元值:

  • 此解决方案使用自定义结构块来隐藏字段和标签。我建议现在使用这种方法,因为它使用wagtail提供的自定义功能供您使用。尽管文档中没有提到以这种方式使用组元,但组元是有文档记录的,应该可以依赖(如果有必要,可以很容易地用另一个细节替换)
  • 对于这个答案上发生的任何人,我建议在使用之前检查wagtail文档,因为项目的开发似乎很快,如果他们提供了一种“内置”的方式来生成隐藏字段,我一点也不会感到惊讶
  • 在我自己的测试中,我没有得到OP在评论中提到的缩进。只要结构本身是顶级元素,所有子元素都默认保持对齐-因此它们与结构块之外的任何字段对齐
  • 当然,您可以创建基本类型的自定义块(例如自定义CharBlock)并将小部件kwarg指定为forms.HiddenInput,但您仍然需要处理标签-传递类名kwarg只会将其应用于输入,而不是标签等。使用自定义基本块意味着永远保留它们或。这避免了所有这些问题
  • 当然,这些都可以通过一些JS/css轻松实现,但前提是我们只需要html解决方案

    class StructWithHiddenFields(StructBlock):
      classMeta:
        form_template = "blocks/admin/struct_with_hidden_fields.html"
    
    """Obviously you'd want to copy the template from the wagtail one 
    for StructBlocks (wagtailadmin/block_forms/struct.html) to ensure 
    similar behaviour and then add a bit of logic for the hiding.  
    This might look like this:"""  
    
    #blocks/admin/struct_with_hidden_fields.html template:
    
    <div class="{{ classname }}">
      {% if help_text %}
       <div class="sequence-member__help help"><span class="icon- 
         help-inverse" aria-hidden="true"></span>{{ help_text }} 
       </div>
      {% endif %}
    
      <ul class="fields">
        {% for child in children.values %}
          {% if child.block.meta.group != "hidden-input" %}
            <li{% if child.block.required %} class="required"{% endif %}>
            {% if child.block.label %}
                <label{% if child.id_for_label %} for="{{ child.id_for_label }}"{% endif %}>{{ child.block.label }}:</label>
            {% endif %}
            {{ child.render_form }}
            </li>
         {% endif %}
        {% endfor %}
      </ul>
      {% for child in children.values %}
        {% if child.block.meta.group == "hidden-input" %}
           <input type="hidden" id="{{ prefix }}-{{child.block.label}}" name="{{ prefix }}-{{child.block.label}}" value="{{child.block.value}}">
        {% endif %}
      {% endfor %}
    </div>
    
    #Usage:
    
    class MySpecificBlockWithHiddenFields(StructWithHiddenFields):
      normal_field = CharBlock(required=False)
      hidden_field = IntegerBlock(required=False, group="hidden-input")
    
    类StructWithHiddenFields(StructBlock):
    classMeta:
    form_template=“blocks/admin/struct_with_hidden_fields.html”
    “”“显然,您希望从摇尾模板复制该模板
    对于StructBlocks(wagtailadmin/block_forms/struct.h