【发布时间】:2021-08-10 21:38:34
【问题描述】:
我有一个包含表单的 django bootstrap 4 模板 (wordcloud.html)。该表单最初是在 wordcloud.html 中创建为原始 html,并且该模板的视图填充字段。表单 (create_wordcloud_form) 使用 post 将数据发送到不同的视图 (create_wordcloud_view.py)。原开发者没有使用django内置的template/form/view结构,所以没有form.py也没有form模板。
我需要解决的问题是验证表单。它必须是服务器端验证,因为需要针对其中一个数据库对其中一个字段进行测试,以防止出现重复字段。
我是否需要使用crispy-forms将整个混乱重构为标准的django模板/表单/视图习语,或者有没有办法使用我已有的内容并从处理表单数据的视图中返回一些错误消息?
验证字段的代码很简单。如果出现字段错误,我不确定如何构造 return 语句,因为 wordcloud.html 呈现在不同的视图中。
create_wordcloud_view:
@method_decorator(login_required, name='post')
class CreateWordCloud(View):
def post(self, request):
logger.debug("CreateWordCloud START")
q_dict = request.POST
logger.debug("q_dict=%s" % q_dict)
sources = []
filters = {}
cloud_name = None
for key in q_dict:
logger.debug("key=%s" % key)
if key == 'csrfmiddlewaretoken':
continue
if key in ["Titles", "Descriptions", "Comments", "Translations", "Text"]:
sources.append(key)
elif key == 'wordcloud_name':
cloud_name = q_dict['wordcloud_name']
else:
values = q_dict.getlist(key)
if len(values) == 1:
filters[key] = values[0]
else:
filters[key] = values
# Need to add field validation here
# 1. Must have at least one source
# 2. wordcloud_name must not be in the table of wordclouds
# 3. Alert user that no words were found for the combination of sources
# and filters selected
from wordcloud.tasks import create_wordcloud_task_3
create_wordcloud_task_3(None, cloud_name, sources, filters=filters)
# If the form data is valid and more than a few words are returned from
# create_wordcloud_task_3, then redirect to wordcloud.html
return redirect("/memorabilia/wordcloud.html", permanent=False)
# If form is invalid or no words returned from create_wordcloud_task_3,
# return to wordcloud.html with original data and appropriate field error
# messages.
return ????
create_wordcloud_form(来自wordcloud.html 模板的 sn-p):
<div id="wordcloud_form" style="display: none;">
<form action="/wordcloud/ajax/create_wordcloud/" class="was-validated" method="post">{% csrf_token %}
<div class="form-row">
<div class="col-md-12">
<p>First, select the source of words:</p>
</div>
</div>
<div class="form-row">
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="source_text" name="Text">
<label class="form-check-label" for="source_text">Text</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="source_translation" name="Translations">
<label class="form-check-label" for="source_translation">Translations</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="source_titles" name="Titles">
<label class="form-check-label" for="source_titles">Titles</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="source_descriptions" name="Descriptions">
<label class="form-check-label" for="source_descriptions">Descriptions</label>
</div>
<div class="form-check form-check-inline">
<input class="form-check-input" type="checkbox" id="source_comments" name="Comments">
<label class="form-check-label" for="source_comments">Comments</label>
</div>
<span>{{ form_sources_required }}
</div>
<div class="form-row mt-3">
<div class="col-md-12">
<p>Second, filter documents based on the metadata, if desired:</p>
</div>
</div>
{% for category in categories %}
{% if forloop.counter0|divisibleby:3 %}
<div class="form-row">
{% endif %}
<div class="col">
<label>{{ category.label }}</label>
<select class="selectpicker" name="{{ category.label }}" multiple data-size="10">
{% for option in category.options %}
<option>{{ option }}</option>
{% endfor %}
</select>
</div>
{% if forloop.counter|divisibleby:3 %}
</div>
{% endif%}
{% endfor %}
<div class="form-row mt-3">
<div class="col-md-12">
<div class="form-group">
<label for="wordcloud_name">Finally, give your wordcloud a name</label>
<input type="text" name="wordcloud_name" class="form-control" id="wordcloud_name" placeholder="Enter your wordcloud name">
<div class="invalid-feedback">{{ form_cloud_name_required }} {{ form_duplicate_cloud_name_error }}</div>
</div>
</div>
</div>
<div class="form-row mt-3">
<div class="col-md-12">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
【问题讨论】:
-
如果需要,您可以只使用表单来呈现错误和验证,同时将表单呈现保留为您拥有的当前手动编写的 HTML(可能需要更改
name属性以匹配如果需要)。虽然我会建议你是否愿意去折射:)
标签: django bootstrap-4 django-forms