在我建立的Django社交网站中,用户可以在普通房间聊天,或创建私人群组。
每个用户都有一个主仪表板,其中所有对话都是一起出现,堆叠在一起(由20个对象分页)。我称之为unseen activity
页面。此页面上的每个看不见的对话都有一个文本框,用户可以直接键入回复。此类回复是通过<form>
内的POST请求提交的。
每个action
的{{1}}属性指向不同的网址,具体取决于提交的回复类型(例如<form>
或home_comment
)。这是因为它们具有不同的验证和处理要求等。
问题是这样的:如果引发了ValidationError(例如,用户输入了带有禁止字符的回复),它会显示在{{1>中的多个表单上页面,而不仅仅是它生成的特定表单。如何确保所有ValidationErrors仅显示在它们源自的表单上?一个说明性的例子会很棒!
附加到所有这些的表单类称为group_reply
,并且定义如下:
unseen_activity
模板如下:
UnseenActivityForm
现在对于观点。我不会在一个单一的过程中处理所有事情。一个函数负责为GET请求生成内容,其他函数负责处理POST数据处理。这是:
class UnseenActivityForm(forms.Form):
comment = forms.CharField(max_length=250)
group_reply = forms.CharField(max_length=500)
class Meta:
fields = ("comment", "group_reply", )
def __init__(self,*args,**kwargs):
self.request = kwargs.pop('request', None)
super(UnseenActivityForm, self).__init__(*args, **kwargs)
def clean_comment(self):
# perform some validation checks
return comment
def clean_group_reply(self):
# perform some validation checks
return group_reply
注意:代码是我实际代码的简化版本。如果您需要,请询问更多细节。
答案 0 :(得分:1)
在上述评论中讨论后:
我建议您为视图中的每个实例创建一个表单。我已经重构了你的代码,以便有一个返回对象列表的函数,你可以在group_reply
和def get_object_list_and_forms(request):
notifications = retrieve_unseen_notifications(request.user.id)
page_num = request.GET.get('page', '1')
page_obj = get_page_obj(page_num, notifications, ITEMS_PER_PAGE)
if page_obj.object_list:
oblist = retrieve_unseen_activity(page_obj.object_list)
else:
oblist = []
# here create a forms dict which holds form for each object
forms = {}
for obj in oblist:
forms[obj.pk] = UnseenActivityForm()
return page_obj, oblist, forms
def unseen_activity(request, slug=None, *args, **kwargs):
page_obj, oblist, forms = get_object_list_and_forms(request)
context = {
'object_list': oblist,
'forms':forms,
'page':page_obj,
'nickname':request.user.username
}
return render(request, 'user_unseen_activity.html', context)
函数中使用它们:
{% for unseen_obj in object_list %}
<!-- use the template tag in the linked post to get the form using obj pk -->
{% with forms|get_item:unseen_obj.pk as form %}
{% if unseen_obj.type == '1' %}
{% if form.comment.errors %}{{ form.comment.errors.0 }}{% endif %}
<form method="POST" action="{% url 'process_comment' pk %}">
{% csrf_token %}
{{ form.comment }}
<button type="submit">Submit</button>
</form>
{% elif unseen_obj.type == '2' %}
{% if form.group_reply.errors %}{{ form.group_reply.errors.0 }}{% endif %}
<form method="POST" action="{% url 'process_group_reply' pk %}">
{% csrf_token %}
{{ form.group_reply }}
<button type="submit">Submit</button>
</form>
{% endif %}
{% endwith %}
{% endfor %}
现在,您需要使用对象ID from forms
dict访问模板中的表单。
def unseen_reply(request, pk=None, *args, **kwargs):
if request.method == 'POST':
form = UnseenActivityForm(request.POST,request=request)
if form.is_valid():
# process cleaned data
else:
page_obj, oblist, forms = get_object_list_and_forms(request)
# explicitly set the form which threw error for this pk
forms[pk] = form
context = {
'object_list': oblist,
'forms':forms,
'page':page_obj,
'nickname':request.user.username
}
return render(request, 'user_unseen_activity.html', context)
在处理回复时,您再次需要附加与特定对象pk抛出错误的表单:
{{1}}