使用占位符和错误验证为 CreateView 和 UpdateView 制作自定义模板
Making a custom template for CreateView and UpdateView with placeholders and error validation
我在学习 Django 的同时制作了一个通用博客。
我有一个 ArticleCreateView
和 ArticleUpdateView
,我正在尝试制作一个两个视图都可以共享的自定义模板。
据我了解,CreateView
和 UpdateView
默认使用相同的模板 (article_form.html
),这是我要修改的模板。
我的 models.py 中有以下内容:
class Article(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
# def __str__ ...
# def get_absolute_url ...
在我的 views.py:
class ArticleCreateView(CreateView):
model = Article
fields = ['title', 'body']
template_name = 'article_form.html'
class ArticleCreateView(CreateView):
model = Article
fields = ['title', 'body']
template_name = 'article_form.html'
在我的模板中包含以下内容 article_form.html 有效:
<form method='post'>
{{ form.as_p }}
<button>
Publish
</button>
</form>
不过我想让它更花哨,加载 CSS,简化版本是:
<form method='post'>
{% csrf_token %}
<fieldset class="fieldset-class">
{{ form.title.errors }}
<input
class="form-class"
type="text"
placeholder="Article Title"
name="{{ form.title.name }}"
value="{{ form.title.value }}"
/>
</fieldset>
<fieldset class="form-group">
{{ form.body.errors }}
<textarea
class="form-control"
rows="8"
placeholder="Article Body"
name="{{ form.body.name }}"
>{{ form.body.value }}</textarea>
</fieldset>
</form>
我想要的是这样一种形式:
- 在空白字段中有占位符(而不是标签)
- 具有基于模型的错误验证(
max_length
得到尊重,两个字段都是 required
,无需我指定)
- 提交后不删除输入的值
以上 html 执行以下操作:
- 提交空字段会引发错误,任何输入的值都会被保留(好)
- 空字段有
None
而不是占位符(问题)
将上面 html 中的 object.title
和 object.body
替换为 form.title.value
和 form.body.value
会执行以下操作:
- 提交空字段会引发错误,但也会清除输入的值(问题)
- 空白字段有正确的占位符(好)
我已经阅读了文档的 Built-in template tags and filters, Rendering fields manually, Rendering form error messages, Looping over the form’s fields, and Attributes of BoundField,在 SO 和 GitHub 上寻找了类似的代码,阅读了 {{ form.as_p }}
呈现的源代码,但我没有找到简单的解决方案,尽管据说有常见用例。
我唯一能想到的就是到处推{% if %}
语句在placeholder
和value
之间进行选择,或者得到一些第三方库,比如crispy-forms, 但感觉应该存在一个更 pythonic 的解决方案。
一如既往,我在 SO 上发布问题后立即找到了答案。
内置模板过滤器default_if_none
解决了问题:
<input
class="form-class"
type="text"
placeholder="Article Title"
name="{{ form.title.name }}"
value="{{ form.title.value|default_if_none:'' }}"
/>
我在学习 Django 的同时制作了一个通用博客。
我有一个 ArticleCreateView
和 ArticleUpdateView
,我正在尝试制作一个两个视图都可以共享的自定义模板。
据我了解,CreateView
和 UpdateView
默认使用相同的模板 (article_form.html
),这是我要修改的模板。
我的 models.py 中有以下内容:
class Article(models.Model):
title = models.CharField(max_length=100)
body = models.TextField()
# def __str__ ...
# def get_absolute_url ...
在我的 views.py:
class ArticleCreateView(CreateView):
model = Article
fields = ['title', 'body']
template_name = 'article_form.html'
class ArticleCreateView(CreateView):
model = Article
fields = ['title', 'body']
template_name = 'article_form.html'
在我的模板中包含以下内容 article_form.html 有效:
<form method='post'>
{{ form.as_p }}
<button>
Publish
</button>
</form>
不过我想让它更花哨,加载 CSS,简化版本是:
<form method='post'>
{% csrf_token %}
<fieldset class="fieldset-class">
{{ form.title.errors }}
<input
class="form-class"
type="text"
placeholder="Article Title"
name="{{ form.title.name }}"
value="{{ form.title.value }}"
/>
</fieldset>
<fieldset class="form-group">
{{ form.body.errors }}
<textarea
class="form-control"
rows="8"
placeholder="Article Body"
name="{{ form.body.name }}"
>{{ form.body.value }}</textarea>
</fieldset>
</form>
我想要的是这样一种形式:
- 在空白字段中有占位符(而不是标签)
- 具有基于模型的错误验证(
max_length
得到尊重,两个字段都是required
,无需我指定) - 提交后不删除输入的值
以上 html 执行以下操作:
- 提交空字段会引发错误,任何输入的值都会被保留(好)
- 空字段有
None
而不是占位符(问题)
将上面 html 中的 object.title
和 object.body
替换为 form.title.value
和 form.body.value
会执行以下操作:
- 提交空字段会引发错误,但也会清除输入的值(问题)
- 空白字段有正确的占位符(好)
我已经阅读了文档的 Built-in template tags and filters, Rendering fields manually, Rendering form error messages, Looping over the form’s fields, and Attributes of BoundField,在 SO 和 GitHub 上寻找了类似的代码,阅读了 {{ form.as_p }}
呈现的源代码,但我没有找到简单的解决方案,尽管据说有常见用例。
我唯一能想到的就是到处推{% if %}
语句在placeholder
和value
之间进行选择,或者得到一些第三方库,比如crispy-forms, 但感觉应该存在一个更 pythonic 的解决方案。
一如既往,我在 SO 上发布问题后立即找到了答案。
内置模板过滤器default_if_none
解决了问题:
<input
class="form-class"
type="text"
placeholder="Article Title"
name="{{ form.title.name }}"
value="{{ form.title.value|default_if_none:'' }}"
/>