如何在 Django 模型字段上设置任意属性,然后在 ModelForm 中访问它们?
Django 的作用
Django 的模型字段“空白”属性,以及当您创建 ModelForm 时它被否定并转变为表单字段“必需”属性的方式,非常酷。它允许我在其所属的模型上设置属性,但在处理从它创建的 ModelForm 时可以使用“required”属性。在模板中渲染时提供“必需”意味着我可以做一些很酷的事情,例如向必填字段的显示标签添加星号。
模型
class Employee(models.Model):
name = models.CharField(blank=False)
public_bio = models.TextField(blank=False)
salary= models.DecimalField(max_digits=15, decimal_places=2, blank=False)
personnel_notes = models.TextField(blank=True)
模板(使用 ModelForm)
{% for field in form %}
<p>
{{ field.label }}{% if field.required %}*{% endif %}
{{ field }}
</p>
{% endfor %}
我希望它做什么
但如果我想用我自己的新属性来做到这一点该怎么办?它不需要以空白的方式否定/翻译 --> required 确实如此,但我希望在模型字段上定义的新属性可以在我的表单字段上访问。例如,假设我想向用户明确说明可能发布哪些字段:
模型
class Employee(models.Model):
name = models.CharField(blank=False, publishable=True)
public_bio = models.TextField(blank=False, publishable=True)
salary= models.DecimalField(max_digits=15, decimal_places=2, blank=False, publishable=False)
personnel_notes = models.TextField(blank=True, publishable=False)
模板(使用 ModelForm)
{% for field in form %}
<p>
{{ field.label }}{% if field.required %}*{% endif %}
{% if field.publishable %}(may be published){% endif %}
{{ field }}
</p>
{% endfor %}
有什么方法可以做到这一点吗?尝试一下,我立即遇到了模型定义的问题,其中 django.db.models.fields.Field.__init__() 甚至不接受 kwargs。如果这是不可能的,有什么解决方法来获得所需行为的想法吗?
What Django Does
Django's Model Field "blank" attribute, and the way it gets negated and turned into the Form Field "required" attribute when you create a ModelForm, is pretty cool. It allows me to set the property on the model where it belongs, but have the "required" attribute available when handling a ModelForm created from it. Having "required" available when rendering in a template means I can do cool things like add an asterisk to the display labels of required fields.
Model
class Employee(models.Model):
name = models.CharField(blank=False)
public_bio = models.TextField(blank=False)
salary= models.DecimalField(max_digits=15, decimal_places=2, blank=False)
personnel_notes = models.TextField(blank=True)
Template (using ModelForm)
{% for field in form %}
<p>
{{ field.label }}{% if field.required %}*{% endif %}
{{ field }}
</p>
{% endfor %}
What I Want It to Do
But what if I want to do that with my own, new attribute? It doesn't need to be negated/translated the way blank --> required does, but I want my new attribute, defined on the Model Field, to be accessible on my FormFields. For example, let's say I want to make explicit to the user which fields might be published:
Model
class Employee(models.Model):
name = models.CharField(blank=False, publishable=True)
public_bio = models.TextField(blank=False, publishable=True)
salary= models.DecimalField(max_digits=15, decimal_places=2, blank=False, publishable=False)
personnel_notes = models.TextField(blank=True, publishable=False)
Template (using ModelForm)
{% for field in form %}
<p>
{{ field.label }}{% if field.required %}*{% endif %}
{% if field.publishable %}(may be published){% endif %}
{{ field }}
</p>
{% endfor %}
Is there any way to do this? Trying it, I'm running into an issue immediately with the model definition, where django.db.models.fields.Field.__init__()
doesn't even accept kwargs. If this isn't possible, any ideas for workarounds to get the desired behavior?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请注意,publishable 应该是 forms.Field 上的属性,而不是 models.Field 上的属性,以便它将出现在模板中。
您可以将其显式添加到您希望在表单启动时可发布的字段上,并且在渲染时可以使用它:
Note that publishable should be a property on the forms.Field, not on the models.Field, so that it will appear in the template.
You can add this explicitly on the fields you wish to have publishable in the form's initiation, and it will be available to you while rendering:
您还可以为模型字段创建一种装饰器:
然后覆盖表单的
__init__
以使用这些字段。另外不要忘记在模板中使用
{{ form.name }}
返回 BoundField。要获取原始表单字段,您应该使用{{ form.name.field }}
。You can also make kind of decorator for model fields:
Then override form's
__init__
to use these fields.Also don't forget that using
{{ form.name }}
in template returns BoundField. To get original form field you should use{{ form.name.field }}
.