{{ form.tags | as_crispy_field }}
未按预期呈现。在创建初始帖子时,相同的脆皮表单语法可以完美地工作和呈现
按提交会导致服务器 500 错误。测试结果内联记录:
<!-- templates/update_question.html -->
{% extends "base.html" %}
{% load static %}
{% load crispy_forms_tags %}
{% block extra_head %}
<!-- django-quill-editor Media -->
{% include 'django_quill/media.html' %}
{% endblock %}
{% block content %}
<main class="flex-shrink-0 main-bg">
<div class="container-question my-5">
[...]
<form id="standards-form" method="post" action="{% url 'question_update' slug=question.slug %}">
{% csrf_token %}
[...]
<h2 class="text-center">Subject line</h2>
{{ form.subject | as_crispy_field }} <!-- rendering as expected-->
<br>
<h2 class="text-center">Details</h2>
{{ form.content | as_crispy_field }} <!-- rendering as expected-->
<br>
<h2 class="text-center">Tags</h2>
<div class="tag-input">
<div class="input">
<div>
<i class="fa fa-tags"></i>
{{ form.tags | as_crispy_field }} <!--not rendering as expected: reading as [<Tag: tag1>, <Tag: tag2>, <Tag: tag3>]. Expecting tag1 tag2 tag3 to be retrieved from django-taggit's TaggableManager-->
</div>
</div>
<div class="tag-list mb-4"></div>
</div>
<button type="submit" class="btn btn-primary " id="question-submit">Submit</button>
</form>
</div>
</main>
{% endblock %}
表单在此类中处理,我尝试过打印日志并将 init 函数移至顶部。
# main_forum/forms/question_form.py
# This file contains the form for the Question model. The QuestionForm class will be used to create and update questions in the forum.
from django import forms
from django.contrib.auth.models import User
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit
from ..models import Question, Answer
from django_quill.forms import QuillFormField
from taggit.forms import TagField
from django.contrib.auth.forms import PasswordChangeForm
class QuestionForm(forms.ModelForm):
[...]
tags = forms.CharField(required=False)
class Meta:
model = Question # Specifies the model in models.py associated with this form
fields = ['subject', 'content', 'tags']
def __init__(self, *args, **kwargs):
"""
This is for checking if the form is bound to an existing instance, i.e. if the form is being used to update an existing question.
"""
super(QuestionForm, self).__init__(*args, **kwargs)
[...]
if self.instance.pk:
self.fields['tags'].initial = ' '.join(tag.name for tag in self.instance.tags.all()) # Pre-populate the tags field with the existing tags
print('tags initial:', self.fields['tags'].initial) # PASS. prints as tags initial: tag1 tag2 tag3
[...]
def clean_tags(self):
tags = self.cleaned_data.get('tags', '')
return tags
def save(self, *args, **kwargs):
instance = super(QuestionForm, self).save(commit=False)
instance.save()
# Handling tags here
tags = self.cleaned_data.get('tags', '')
tag_names = tags.split()
print('tag_names after tag.split', tag_names) # expecting ['tag1', 'tag2', 'tag3'] in order to be saved correctly etc. PASS
instance.tags.clear()
for tag_name in tag_names:
instance.tags.add(tag_name.strip()) # Ensure tag is stripped of extra whitespace
print('instance.tags.all:', instance.tags.all()) # PASS <QuerySet [<Tag: tag1>, <Tag: tag2>, <Tag: tag3>]> etc.
if self.instance.pk:
# If this is an update, save the instance again
instance.save() # Save the instance again to save the many-to-many relationships
print('instance saved:', instance) # testing: leads to server 500 error
return instance
看来我能找到的最佳解决方案是替换 {{ form.tags | as_crispy_field }} 带有自定义输入:
<input type="text" name="tags" id="id_tags id_tags_update" value="{{ question.tags.all|join:' ' }}" /> <!-- this correctly renders the tags as tag1 tag2 tag3 etc.-->