Django表单 - 呈现表单并重定向

时间:2017-06-06 15:45:51

标签: django python-2.7 django-forms http-post

我正在尝试创建一个“添加用户”#39;该功能只会将您从下拉菜单中选择的用户添加为您的连接。我正在使用Django Forms中的ModelChoiceField,以便我可以从下拉列表中的User模型中获取现有用户。

forms.py

from django import forms
from django.contrib.auth.models import User


class NetworkForm(forms.Form):
    user_id = forms.ModelChoiceField(queryset=User.objects.all(), label='',
                                       widget=forms.Select(attrs={'class': 'all_users'}))

views.py

@login_required
def index(request):
    user_list = User.objects.exclude(username=request.user)
    return render(request, 'chat/index.html', {'user_list': user_list})
  

现在我只是打印表单以查看输出

@login_required
def add_user(request):
    form = NetworkForm()
    if request.method == 'POST':
        form = NetworkForm(request.POST)
        if form.is_valid():
            print form 
            return redirect(request.META['HTTP_REFERER'])

    errors = form.errors or None

    return render(request, 'chat/index.html', {
        'form': form,
        'errors': errors,
    })

的index.html



<div class="row">
<form action="{% url 'chat:add_user' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>
</div>
&#13;
&#13;
&#13;

urls.py

urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^add_user/$', views.add_user, name='add_user'),]

目前正在呈现的方式是:我有我的主索引页面,我没有看到任何下拉列表,即 enter image description here

当我点击提交按钮时,它会将我移动到index / add_user,在那里我得到一个用户下拉列表(带有警告&#34;需要此字段)和再次提交按钮。 enter image description here

最后,当我在这个新页面中选择一个用户并点击提交时,最后会打印出我最终想要的表单。enter image description here

我想要它,在索引页面本身有完整的下拉列表,并在我提交表单时保留在那里。 然后我会挂钩显示用户他们已添加到该表单下方的用户(&#39; print&#39;仅用于调试目的 - 不是我听过的好方法)。 我理解post请求必须转到add_user页面,我可以从那里重定向。在过去的6个小时里,我尝试了各种替代品,但还没有任何效果。为长期道歉,尽可能地提供信息。非常感谢你们。你太棒了。

修改 现在已经在索引页面中呈现表单(来自@ fazil-zaid的建议),但问题仍然只在于提交&#39;按钮最初出现在索引上,除非我点击提交后显示下拉列表和提交。再次,在第二次点击时,表单将被提交。

修改-2 我在想:

<form action="{% url 'chat:index' %}" method="post">{% csrf_token %}
{{ form.as_p }}
    <button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>

这可能是问题所在,根据当前逻辑,除非用户采取表单的操作,即点击按钮{{form.as_p}}将不会出现。然后我试了一下:

{{ form.as_p }}
<form action="{% url 'chat:index' %}" method="post">{% csrf_token %}
    <button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>

还没有工作。 POST请求不会发送任何数据(这是可以理解的)。

2 个答案:

答案 0 :(得分:1)

如果您希望表单位于索引页面中,则可以将其包含在索引视图中。

def index(request):
    if request.method == 'POST':
        form = NetworkForm(request.POST)
        if form.is_valid():
            #do what you wanna do
            #with the form data.
    else:
        form = NetworkForm()
    render(request, 'chat/index.html', { 'form': form})

在模板中,

<div class="row"> 
<form action="" method="post"> 
{% csrf_token %} 
{{ form.as_p }} 
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button> 
</form> 
</div>

您不是在渲染另一个模板,而是使用相同的&#39; index.html&#39;。然后,多视图就是多余的。索引页面可以包含表单并自行呈现。根据我的理解,不需要重定向。

如果您在索引页面中显示该表单,则无需添加add_user视图。

对于您的问题,请尝试更改&#34;类&#34;表单字段的属性,可能是这样的,

class NetworkForm(forms.Form):
    user_id = forms.ModelChoiceField(queryset=User.objects.all(), widget=forms.Select(attrs={'class': 'form-control'}))

答案 1 :(得分:1)

<强>解决方案: 当使用GET在第一个实例中调用页面时,表单无效,因为它寻求POST方法。因此,所有方法都需要在视图中更改为POST,即

@login_required
def index(request):
    user_list = User.objects.exclude(username=request.user)
    form = NetworkForm()
    if request.method == 'POST':
        form = NetworkForm(request.POST)
        if form.is_valid():
            print form.data
            return redirect(request.META['HTTP_REFERER'])

    return render(request, 'chat/index.html', {
        'user_list': user_list,
        'form': form,
    })

早些时候,索引使用GET将数据呈现到索引页面,并使用POST来使用表单。现在,一切正常。 由于您提到要在索引视图中包含所有内容,而不是为表单创建单独的视图,因此特别向@fazil-zaid提出单挑。您的代码除了Stack之外还指出了这一点。