【问题标题】:Django: access to attributes of custom model field from html templateDjango:从 html 模板访问自定义模型字段的属性
【发布时间】:2021-04-22 16:37:47
【问题描述】:

我实现了一个自定义模型字段:

class CustomCharField(models.CharField):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.my_attr = "MY_ATTR"

现在我希望能够在迭代 change_form_template 中的所有模型字段时显示该附加属性:

{% block field_sets %}
    {% for fieldset in adminform %}
        {% for line in fieldset %}
            {% for field in line %}
                {{ field.field }}

                {% if field.field.my_attr %}
                    {{ field.field.my_attr }}
                {% endif %}

            {% endfor %}
        {% endfor %}
    {% endfor %}
{% endblock %}

很遗憾,my_attr 不可见。我在 django 文档中搜索正确的方法,但没有任何成功。我也尝试使用自定义的form_class(继承自django.forms.fields.CharField

编辑:

好的,所以我需要自定义表单字段和模型字段。给定以下代码,我应该更改什么才能使其正常工作? (当然我忽略了在该示例中传递属性值)。为什么模板仍然无法访问来自CustomFormFieldmy_attr

class CustomFormField(fields.CharField):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.my_attr = "MY_ATTR2"

class CustomCharField(models.CharField):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.my_attr = "MY_ATTR"

    def formfield(self, **kwargs):
        defaults = {'form_class': CustomFormField}
        defaults.update(kwargs)
        return super().formfield(**defaults)

【问题讨论】:

  • 如果要自定义模板中的某个字段,则需要创建自己的forms.CharField,而不是models.CharField。否则,就像尝试在模板中显示另一个模型字段属性一样,这是不可能的(例如,您不能在模板中打印 field.defaultfield.required)。
  • 您在这里创建了一个自定义模型字段CustomCharField(models.CharField),而不是表单字段。 field.field 为您提供绑定字段的表单字段,而不是模型字段。
  • @Guillaume 谢谢,我编辑了这个问题。
  • 谢谢,@AbdulAzizBarkat

标签: python django django-forms


【解决方案1】:

好的,感谢@AbdulAzizBarkat 和@Guillaume 的建议,我终于设法解决了这个问题。

为了在 HTML 模板中暴露模型字段的属性,还需要实现自定义表单字段并在 formfield 方法中传递 default dict 中的属性:

from django.db import models
from django.forms import fields

class CustomFormField(fields.CharField):
    def __init__(self, my_attr, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.my_attr = my_attr


class CustomCharField(models.CharField):
    def __init__(self, my_attr, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.my_attr = my_attr

    def formfield(self, **kwargs):
        defaults = {'form_class': CustomFormField, "my_attr": self.my_attr}
        defaults.update(kwargs)
        return super().formfield(**defaults)

另一个变化是访问通过设置change_form_template值指定的HTML模板中的属性的方式。在这种情况下,它应该是{{ field.field.field.my_attr }}

【讨论】:

    猜你喜欢
    • 2022-01-24
    • 2012-06-09
    • 2014-06-10
    • 2011-06-06
    • 2012-10-13
    • 2013-03-16
    • 2013-07-23
    • 1970-01-01
    • 2014-11-23
    相关资源
    最近更新 更多