当 Django 有其他机制时,我不想使用自己的 JS 或更改模板。
我尝试了三种方法,第一种,如中所述 如何将占位符文本添加到-django-admin-field和文档。
from django import forms
class AppointmentAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
kwargs['widgets'] = {
'name': forms.TextInput(attrs={'placeholder': 'Type here'})
}
return super().get_form(request, obj, **kwargs)
然后django-add-placeholder-text-to-form-field中描述的方法,稍作修改以解决Python错误。
class AppointmentAdmin(admin.ModelAdmin):
def get_form(self, request, obj=None, **kwargs):
form = super().get_form(request, obj, **kwargs)
form.base_fields['customer'].widget.attrs["placeholder"] = "Type here"
return form
最后,使用formfield_overrides:
class AppointmentAdmin(admin.ModelAdmin):
formfield_overrides = {
models.TextField: { "widget":forms.TextInput(attrs={'placeholder':'Type here'})},
}
这些都不起作用。我一定忽略了一些简单的事情?
models.py的相关部分:
class Appointment(models.Model):
customer = models.ForeignKey(Customer, blank=False, null=True, default=None, on_delete=models.CASCADE, related_name='appointments')
autocomplete_fields = ["customer"]
我删除了
autocomplete_fields
行,但对占位符没有任何影响。
(旁注:我认为 autocomplete_fields 应该有一个占位符选项,而不是要求如上所述的所有跳过。)
models.py 中字段上的“help_text”选项几乎可以作为占位符的廉价替代品,只是它在该程序的其他部分没有任何意义。
这是 Django 使用上面第二种方法生成的 HTML(form.base_fields...等):
<div class="related-widget-wrapper" data-model-ref="customer">
<select name="customer" placeholder="Type here" required="" id="id_customer" class="admin-autocomplete select2-hidden-accessible" data-ajax--cache="true" data-ajax--delay="250" data-ajax--type="GET" data-ajax--url="/admin/autocomplete/" data-app-label="giraffe" data-model-name="appointment" data-field-name="customer" data-theme="admin-autocomplete" data-allow-clear="false" data-placeholder="" lang="en" data-select2-id="id_customer" tabindex="-1" aria-hidden="true">
</select>
<span class="select2-container select2-container--admin-autocomplete select2-container--open" style="position: absolute; top: 164.484px; left: 15px;">
<span class="select2-dropdown select2-dropdown--above" dir="ltr" style="width: 249px;">
<span class="select2-search select2-search--dropdown">
<input class="select2-search__field" type="search" tabindex="0" autocomplete="off" autocorrect="off" autocapitalize="none" spellcheck="false" role="searchbox" aria-autocomplete="list" aria-controls="select2-id_customer-results">
</span>
<span class="select2-results">
<ul class="select2-results__options" role="listbox" id="select2-id_customer-results" aria-expanded="true" aria-hidden="false">
<li class="select2-results__option" role="option" aria-selected="false" data-select2-id="6">customer name here</li>
(more li and closing of spans here)
更新:Django 使用 Select2 实现自动完成选择框,其 docs 说:
仅对于单选,为了显示占位符值, 您必须将空白作为第一个选项 控制。这是因为浏览器尝试选择第一个选项 默认情况下。如果您的第一个选项非空,浏览器会 显示此内容而不是占位符。
但是 Django 插入客户作为第一个选项。虽然它不是空的,但浏览器不会按照描述的方式显示它,但也许它仍然破坏了 Select2 占位符插入? 也许答案是如何让 Django 插入一个空对象?
autocomplete_fields
是在 ModelAdmin
上定义的,而不是 Model
。
是
attrs['data-placeholder']
而不是attrs['placeholder']
。然而,Django 并没有正确支持它,因为 data-placeholder
被 AutocompleteMixin
覆盖:
class AutocompleteMixin:
...
def build_attrs(self, base_attrs, extra_attrs=None):
...
attrs = super().build_attrs(base_attrs, extra_attrs=extra_attrs)
...
attrs.update({
...
'data-placeholder': '', # Allows clearing of the input.
...
})
return attrs
您可以修补
AutocompleteSelect
小部件以恢复data-placeholder
:
from django.contrib.admin import options
class AutocompleteSelectWithPlaceholder(options.AutocompleteSelect):
def build_attrs(self, base_attrs, extra_attrs=None):
attrs = super().build_attrs(base_attrs, extra_attrs=extra_attrs)
if 'data-placeholder' in base_attrs:
attrs['data-placeholder'] = base_attrs['data-placeholder']
return attrs
options.AutocompleteSelect = AutocompleteSelectWithPlaceholder
用途:
@admin.register(Appointment)
class AppointmentAdmin(admin.ModelAdmin):
autocomplete_fields = ['customer']
def get_form(self, request, obj=None, **kwargs):
form = super().get_form(request, obj, **kwargs)
form.base_fields['customer'].widget.attrs['data-placeholder'] = 'Type here'
return form