我正在尝试通过添加自定义类并使用titlecase而不是仅将首字母大写来定制为表单编写标签的方式。
为此,我编写了自定义过滤器label_with_classes()
,它实际上是Django Boundfield.label_tag
的包装:
from django import template
from django.forms import ChoiceField, BooleanField, DateField, ImageField
from dashboard.forms.widgets import DateFilterWidget, CheckboxSelectDropdown
from titlecase import titlecase
register = template.Library()
def pretty_name(name):
"""Convert 'first_name' to 'First Name'."""
return titlecase(name.replace('_', ' '))
def should_be_active(bound_field):
'''Determine whether the field's label should have Material's "active" class added to it'''
if isinstance(bound_field.field.widget, (DateFilterWidget, CheckboxSelectDropdown)):
return True
return (bound_field.value() and not isinstance(bound_field.field, (ChoiceField, BooleanField)))\
or isinstance(bound_field.field, (DateField, ImageField))
@register.filter(is_safe=True)
def label_with_classes(bound_field, contents=None):
'''Extend Django's label_tag() method to provide the appropriate Materialize CSS classes'''
if not bound_field:
return ''
active = 'active' if should_be_active(bound_field) else ''
invalid = 'invalid' if bound_field.errors else ''
classes = f"{active} {invalid}".strip()
if bound_field.name == 'salesforce_id':
import ipdb; ipdb.set_trace()
contents = contents or pretty_name(bound_field.label)
return bound_field.label_tag(attrs={'class': classes},
contents=contents,
label_suffix='')
在其中设置了特定字段的跟踪记录。
我正在尝试显示具有以下Company
的{{1}}模型的通用视图:
ModelForm
以下是使用这种形式的通用class CompanyForm(forms.ModelForm):
class Meta:
model = Company
fields = [
'name',
'salesforce_id',
'contract_in_place',
'default_package',
'important',
'implementation_date',
'contact',
'customer_notes',
'email_domains',
'lucy_guide',
]
labels = {
'salesforce_id': "Salesforce ID",
'contract_in_place': "Contract In Place",
}
implementation_date = DateField(required=False)
email_domains = SimpleArrayField(
forms.CharField(max_length=255),
required=False,
label="Email Domains -- separate multiple with commas (hicleo.com,startwithcleo.com)")
lucy_guide = forms.ModelChoiceField(
queryset=User.objects.exclude(lucyguide=None).order_by('first_name'),
required=True,
empty_label='Select a Guide',
label="Cleo Guide")
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['default_package'].queryset = self.instance.package_set
:
UpdateView
这是模板:
class EditViewsMixin(DashboardAccessMixin, SuccessMessageMixin):
model = Company
success_url = reverse_lazy('dashboard:companies')
form_class = CompanyForm
class CompanyUpdate(EditViewsMixin, UpdateView):
template_name = 'companies/edit.html'
success_message = "Company '%(name)s' was updated successfully"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['packages'] = self.object.package_set.order_by('name')
return context
问题在于表单看起来像这样:
问题在于所有标签仍在{% load widget_tweaks %}
{% load custom_errors label_with_classes %}
{% csrf_token %}
<div class="row">
<div class="input-field col s12">
{{ form.name|add_error_class:"invalid" }}
{{ form.name|custom_errors }}
{{ form.name|label_with_classes }}
</div>
</div>
<div class="row">
<div class="input-field col s12">
{{ form.salesforce_id|add_error_class:"invalid" }}
{{ form.salesforce_id|custom_errors }}
{{ form.salesforce_id|label_with_classes }}
</div>
</div>
<div class="row">
<div class="input-field col s6">
<div class="radio-wrapper">
{{ form.contract_in_place }}
{{ form.contract_in_place|label_with_classes }}
</div>
</div>
<div class="input-field col s6">
<div class="radio-wrapper">
{{ form.important }}
{{ form.important|label_with_classes }}
</div>
</div>
</div>
{% if packages %}
<div class="row">
<div class="input-field col s12">
{{ form.default_package|add_error_class:"invalid" }}
{{ form.default_package|custom_errors }}
{{ form.default_package|label_with_classes }}
</div>
</div>
{% endif %}
<div class="row">
<div class="input-field col s12">
<span class="datetime-caret">▼</span>
{{ form.implementation_date|add_class:"datepicker"|add_error_class:"invalid"|attr:"placeholder:Select a Date" }}
{{ form.implementation_date|label_with_classes }}
</div>
</div>
<div class="row">
<div class="input-field col s12">
{{ form.contact|add_class:"materialize-textarea" }}
{{ form.contact|label_with_classes }}
</div>
</div>
<div class="row">
<div class="input-field col s12">
{{ form.lucy_guide|add_error_class:"invalid" }}
{{ form.lucy_guide|custom_errors }}
{{ form.lucy_guide|label_with_classes }}
</div>
</div>
<div class="row">
<div class="input-field col s12">
{{ form.email_domains }}
{{ form.email_domains|custom_errors }}
{{ form.email_domains|label_with_classes }}
</div>
</div>
<div class="row">
<div class="input-field col s12">
{{ form.customer_notes|add_class:"materialize-textarea" }}
{{ form.customer_notes|label_with_classes }}
</div>
</div>
d,而我希望如果在titlecase
选项中提供了标签(如https://docs.djangoproject.com/en/2.0/topics/forms/modelforms/#overriding-the-default-fields所述),按原样使用,不带标题框。
但是,我正在努力寻找如何在labels
函数中进行区分的方法。如果我进入调试器,即使我自己没有定义标签(例如,为label_with_classes
字段),我也会看到该标签已经由Django生成:
name
在这种情况下,我如何区分自己生成的标签(通过字段构造函数中的> /Users/kurtpeek/Documents/Dev/lucy2/lucy-web/dashboard/templatetags/label_with_classes.py(37)label_with_classes()
36 import ipdb; ipdb.set_trace()
---> 37 contents = contents or pretty_name(bound_field.label)
38 return bound_field.label_tag(attrs={'class': classes},
ipdb> bound_field.name
'name'
ipdb> bound_field.label
'Name'
ipdb> bound_field.field.label
'Name'
关键字参数或label
中的labels
选项)与自动生成的标签之间是Django吗?