Bootstrap 模式形式的 AJAX 实现(在 Django 上)

Posted

技术标签:

【中文标题】Bootstrap 模式形式的 AJAX 实现(在 Django 上)【英文标题】:AJAX implementation in a Bootstrap modal form (on Django) 【发布时间】:2016-01-29 17:34:03 【问题描述】:

我想让我的模式引导表单在提交按钮被触发时与 AJAX 一起工作。如果我可以推送提交并保留在模式表单页面上,那就太好了,无论是注册成功(在这种情况下,会给出感谢信息)或发生某种错误(在这种情况下,parsleyfy 会处理它)。 这些是我的文件。

-views.py

from django.shortcuts import render_to_response, render, redirect
from django.template import RequestContext
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required

from tentagarden.forms import UserForm, UserProfileForm

def home(request):
    context = RequestContext(request)

    registered = False

    if request.method == 'POST':
        user_form = UserForm(data=request.POST)
        profile_form = UserProfileForm(data=request.POST)

        if user_form.is_valid() and profile_form.is_valid():
            user = user_form.save()

            user.set_password(user.password)
            user.save()

            profile = profile_form.save(commit=False)
            profile.user = user

            if 'picture' in request.FILES:
                profile.picture = request.FILES['picture']

            profile.save()

            registered = True

        else:
            print user_form.errors, profile_form.errors

    else:
        user_form = UserForm()
        profile_form = UserProfileForm()

    return render_to_response(
            'tentagarden/home.html',
            'user_form': user_form, 'profile_form': profile_form, 'registered': registered,
            context)

-home.html

% extends "tentagarden/base.html" %
% load static %

% block content %

<div class="panel-body">
    <h1 id="home">Pack up your bag and go!</h1>

    % if user.is_authenticated %
    <h2>Welcome back,  user.username . Let's explore the World together!</h2>
    % else %

  <!-- Trigger the modal with a button -->
  <h2><a id="myBtn">Subscribe now :)</a></h2>

  <!-- Modal -->
  <div class="modal fade" id="myModal" role="dialog">
    <div class="modal-dialog">

      <!-- Modal content-->
      <div class="modal-content">
        <div class="modal-header">
          <button type="button" class="close" data-dismiss="modal">&times;</button>
          <h3 class="modal-title">Register with Tent a garden</h3>
        </div>
        <div class="modal-body">
        % if registered %

            <h4>Tent a garden says: <strong>thank you for registering!</strong></h4>
            <a href="/">Return to the homepage.</a><br />
            % else %

            <form data-parsley-validate id="user_form" method="post" action="" enctype="multipart/form-data">

                % csrf_token %

                 user_form.as_p 
                 profile_form.as_p 

                <input type="submit" id="submit" class="btn btn-info" name="submit" value="Register" />
            </form>
        % endif %
        </div>
        <div class="modal-footer">
            <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        </div>

    </div>
    </div>
    </div>

    <script>
        $(document).ready(function()
            $("#myBtn").click(function()
                $("#myModal").modal();
            );
        );
    </script>

    <h2>Are you already a member? Then, <a href="/login/">login</a>!</h2>
    % endif %
</div>

% endblock %

-forms.py

from django import forms
from django.forms import ModelForm
from tentagarden.models import UserProfile
from django.contrib.auth.models import User
from parsley.decorators import parsleyfy

@parsleyfy
class UserForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())
    first_name = forms.CharField(required=True)
    last_name = forms.CharField(required=True)
    email = forms.CharField(required=True)

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password')

class UserProfileForm(forms.ModelForm):
    class Meta:
        model = UserProfile
        fields = ('website', 'picture')

我能做什么? 非常感谢!

【问题讨论】:

您当然可以做到这一点,而且看起来您在这里拥有大部分正确的作品。到目前为止,您的代码的哪一部分有效或无效? 一切正常。我点击“立即订阅”,jQuery 脚本触发 Bootstrap 模式窗口,订阅表单出现,用户注册工作完美无缺。唯一的问题是,当我单击“注册”按钮时,表单会消失并返回主页。一切正常,表单工作正常,但我想在模式窗口内显示成功/失败消息,然后 - 仅在此消息之后 - 提供返回主页的可能性。 【参考方案1】:

要使用 ajax 提交此表单,您需要先覆盖提交按钮的默认操作。有几种方法可以做到这一点,但这样的事情应该可以工作:

// With your other jQuery, or in some other script
$(document).ready(function()

    // On form submit, do ajax instead
    $("#user_form").submit(function(e)
        var postUrl = $(this).attr('action')
        var postData = $(this).serialize()
        $.post(postUrl, postData).done(function(data)

            // Did the registration work?
            // As one idea, your you can set your view to return a JSON 
            // object with a 'success' property that you can check here

            if (data.success == 'true')
              // print "success" on the html somewhere
              console.log('it worked!');
            
        );
        e.preventDefault(); // This stops page reload
    );
);

然后您只需将视图 POST 设置为返回 JSON 消息,如下所示:

# At the top of the view
import json
from django.http import HttpResponse

def home(request):
    # ...
    if request.method == 'POST':
        # ...
        if user_form.is_valid() and profile_form.is_valid():
            # ...
            response_data = 
            response_data['success'] = 'true'
            return HttpResponse(json.dumps(response_data), content_type="application/json")

    # ... The GET and other response return

这有意义吗?

【讨论】:

好的,我使用您的代码触发模式窗口,然后填写表格,单击注册,然后...屏幕上没有任何反应。我的意思是,表单已正确提交并且注册顺利,但模式没有给出任何消息。 (我尝试在 jQuery 调用中将“#user_form”更改为“#submit”,当我单击“注册”按钮时,它只返回一个纯页面:““success”:“真"") 将选择器改回#user_form并试试这个:在我写console.log('it worked!');的地方将其更改为alert('it worked');,以便在视图返回时看到一个弹出窗口。在这部分代码中,您可以定义注册成功时会发生什么。也许使用 jQuery 在 $('#submit').after('&lt;span&gt;It worked!&lt;/span&gt;') 之类的地方添加消息

以上是关于Bootstrap 模式形式的 AJAX 实现(在 Django 上)的主要内容,如果未能解决你的问题,请参考以下文章

Bootstrap Modal ajax 保存多条记录,bootstrapValidator

一个Django插件,用于在Bootstrap模式中创建AJAX驱动的表单。

rails 4 bootstrap 3 ajax模式

Bootstrap隐藏模式在使用ajax的Rails 6中不起作用

Bootstrap 3 - 如果手风琴位于通过 ajax 填充的模式内,则不会触发事件 hidden.bs.collapse

Bootstrap 数据表模态 Ajax 成功问题