【问题标题】:Django forms - rendering form and redirectingDjango 表单 - 呈现表单和重定向
【发布时间】:2017-11-07 17:37:05
【问题描述】:

我正在尝试创建一个“添加用户”功能,它将简单地将您从下拉列表中选择的用户添加为您的连接。我正在使用 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>

urls.py

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

目前呈现的方式是:我有我的主索引页面,我没有看到任何下拉菜单,即,

当我单击提交按钮时,它会将我移动到 index/add_user,在那里我会看到一个带有用户的下拉列表(带有警告“此字段是必需的)和一个提交按钮。

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

我想要什么,在索引页面本身中包含带有下拉菜单的完整表单,并在我提交表单时保留在那里。然后我将挂钩以显示用户他们在该表单本身下方添加的用户(“打印”仅用于调试目的 - 虽然不是我听说过的好方法)。 我知道发布请求必须转到 add_user 页面,我可以从那里重定向回来。在过去的 6 个小时里,我尝试了各种替代方案,但没有任何效果。道歉很长,尽可能多地提供信息。非常感谢你们。你真棒。

编辑 现在已经在索引页面中呈现表单(来自@fazil-zaid 的建议),但问题仍然存在,因为最初索引上仅出现“提交”按钮,除非我点击提交,然后出现下拉和提交。同样,在第二次单击时,表单被提交。

Edit-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 请求不发送任何数据(可以理解)。

【问题讨论】:

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


    【解决方案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>
    

    您不是在渲染另一个模板,而是在渲染相同的“index.html”。然后,多视图只是多余的。索引页面可以包含表单并呈现自身。据我了解,不需要重定向。

    如果您在索引页面本身中显示表单,则不需要 add_user 视图。

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

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

    【讨论】:

    • 谢谢伙计。是的,这是可以实现的,我就是这样做的。现在发生的事情是: 1. 索引页面只显示提交按钮。 2. 单击提交,页面保持不变,但现在下拉列表与提交按钮一起出现。 3. 再次点击提交,然后只传输表单数据。如何从图片中删除步骤 1 是最终的问题。 +1 提示删除其他网址。
    • 更新了答案
    • 根据您的建议更改了课程,但仍然无法正常工作。我添加了较早的类,即“all_users”,只是为了使用表单元素完成正确的 CSS。
    • 我在想的是现在的样子,除非用户执行表单操作:
      {% csrf_token %} {{ form.as_p }}
      形式不会出现,因为它受该逻辑的约束。但后来我在
      标签上方尝试了 {{ form.as_p }}。仍然不显示下拉菜单。
    【解决方案2】:

    解决方案: 当页面在第一个实例中使用 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 here,您的代码还以某种方式指出了这一点。

    【讨论】:

    • @fazil-zaid 不确定我是将我的答案标记为答案还是您的答案?你的绝对是一个大指针。你似乎是个资深的堆垛机,请告诉我规范是什么。
    • 由于fazil没有回复,我将我的答案作为答案,建议用户一起查看fazil和我的,因为两者结合得出最终答案。
    猜你喜欢
    • 2014-02-06
    • 2012-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    相关资源
    最近更新 更多