在包含多个表单字段的Django页面中的正确位置显示验证错误

时间:2017-02-21 05:32:40

标签: django django-forms

在我建立的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

注意:代码是我实际代码的简化版本。如果您需要,请询问更多细节。

1 个答案:

答案 0 :(得分:1)

在上述评论中讨论后:

我建议您为视图中的每个实例创建一个表单。我已经重构了你的代码,以便有一个返回对象列表的函数,你可以在group_replydef 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}}