Django 自訂 forms 欄位 HTML
分類
說明
本篇將示範如何自訂 forms 欄位生成的 HTML。
前置作業
範例會使用 bootstrap class,你需要先安裝 bootstrap,否則修改完之後不會看到效果,你也可以使用自訂的 class 或修改其他內容。
為了方便說明假設你已經配置好 app 名字為 my_app
。
目標
示範修改 ImageField
欄位。
備註:/
代表從專案目錄開始
自訂 ClearableFileInput 類別
我將自訂類別存放在 /common/forms/
。
對於 ImageField
或其他的欄位要繼承哪個類別可以這樣看。
# 查看 ImageField
from django.forms import ImageField
# 再查看 FileField
class ImageField(FileField):
# 找到 widget 使用 ClearableFileInput
class FileField(Field):
widget = ClearableFileInput
之後我們將修改 widget
,所以找到 ClearableFileInput
就可以了。
繼承 ClearableFileInput
類別,修改 template_name
的路徑,使用自訂的模板,當然你還可以修改方法,自訂方法,查看 ClearableFileInput
就能了解更多。
/common/forms/bootstrap_clearable_file_input.py
"""bootstrap clearable file input render"""
from django.forms import ClearableFileInput
class BootstrapClearableFileInput(ClearableFileInput):
"""bootstrap clearable file input render"""
template_name = "common/forms/widgets/bootstrap_clearable_file_input.html"
有時候可以直接修改 attrs
就不用自訂模板了,例如:修改 get_context(self, name, value, attrs)
。
# 略
def get_context(self, name, value, attrs):
attrs = {**(attrs or {})}
# 自訂內容
return super().get_context(name, value, attrs)
自訂模板
先複製原本的模板內容再進行調整,例如 ClearableFileInput
原本的 template_name = "django/forms/widgets/clearable_file_input.html"
先到 Django 套件的 templates 找到這個檔案,大概位置在 python3/site-packages/django/forms/templates/django/forms/widgets/clearable_file_input.html
。
我加了 span 標籤和修改 input class 如下。
/common/templates/common/forms/widgets/bootstrap_clearable_file_input.html
{% comment %} clearable file input {% endcomment %}
{% if widget.is_initial %}
{{ widget.initial_text }}: <a href="{{ widget.value.url }}">{{ widget.value }}</a>
{% if not widget.required %}
<span class="form-check form-check-inline">
<input type="checkbox"
name="{{ widget.checkbox_name }}"
id="{{ widget.checkbox_id }}"
class="form-check-input"
{% if widget.attrs.disabled %}disabled{% endif %}>
<label for="{{ widget.checkbox_id }}" class="form-check-label">{{ widget.clear_checkbox_label }}</label>
</span>
{% endif %}
<br>
{{ widget.input_text }}:
{% endif %}
<input type="{{ widget.type }}"
name="{{ widget.name }}"
{% include "django/forms/widgets/attrs.html" %}>
表單
修改欄位的 widgets
forms.py
from django.forms import ModelForm
from common.forms.bootstrap_clearable_file_input import BootstrapClearableFileInput
from my_app.models import Article
class ArticleForm(ModelForm):
"""文章表單"""
class Meta:
model = Article
fields = ["title", "content", "image"]
# 略
widgets = {
"image": BootstrapClearableFileInput,
}
一般的 forms 欄位修改 widget 範例。
forms.py
from django import forms
class CommentForm(forms.Form):
name = forms.CharField()
url = forms.URLField()
comment = forms.CharField(widget=forms.Textarea)
配置
common 是我自訂的,你不一定要放在 common 資料夾裡面,其他照著設定就行了。
settings.py
import django
INSTALLED_APPS = [
# 略
"django.forms",
]
FORM_RENDERER = "django.forms.renderers.TemplatesSetting"
TEMPLATES = [
{
# 略
"DIRS": [
BASE_DIR / "common" / "templates",
django.__path__[0] + "/forms/templates",
],
# 略
}
]
結論
這次水沒有很深,但也夠嗆了,沒事就使用預設欄位就好。
參考
一杯咖啡的力量,勝過千言萬語的感謝。
支持我一杯咖啡,讓我繼續創作優質內容,與您分享更多知識與樂趣!