在Bootstrap模态框中提交Django表单

5 投票
3 回答
13068 浏览
提问于 2025-04-17 23:33

我刚开始学习Django,想弄明白怎么在一个弹窗里提交表单。我有两个Django应用,一个是frontend(前端),另一个是login(登录)。前端应用负责展示页面,而登录应用则处理表单。我在用crispy forms来渲染表单,但就是无法提交这些表单。已经为这个问题纠结了好几天,读了很多相关的帖子,还是搞不定。如果有人能帮帮我,我将非常感激。谢谢大家!我用的是Django 1.6版本。

前端应用的urls.py:

from django.conf.urls import patterns, url
from django.contrib import admin
from frontend import views
from login.views import registration

urlpatterns = patterns('',
    url(r'^$', views.index, name='index'),
    url(r'^about/$', views.about, name='about'),
    url(r'^contact/$', views.contact, name='contact'),
    url(r'^$', 'index', name='index'),
    url(r'^$',views.registration, name='register'),
)

前端应用的views.py:

from django.template import RequestContext
from django.shortcuts import render_to_response
from login.forms import RegistrationForm
from login.forms import LoginForm
from login.views import registration

def index(request):
    return render_to_response('index.html', {'regform':RegistrationForm(),'loginform': LoginForm()} )


def about(request):
    return render_to_response('about.html')

def contact(request):
    return render_to_response('contact.html')

登录应用的urls.py:

from django.conf.urls import patterns, url
from login import views

urlpatterns = patterns('',
   url(r'^register/$', views.registration, name='index.html')

)

登录应用的views.py:

from django.template import RequestContext
from django.shortcuts import render_to_response
from login.forms import RegistrationForm



def registration(request):


    context = RequestContext(request)


    registered = False


if request.method == 'POST':
    
    user_form = RegistrationForm(request.POST)
    

    
    user = user_form.save()

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

    registered = True

   


else:
    user_form = RegistrationForm()
    
return render_to_response('index.html', {'regform': user_form}, context)

def login(request):
   context = RequestContext(request)
   login_form = LoginForm()
   return render_to_response('index.html', {loginform: login_form}, context)

登录应用的forms.py:

from django.contrib.auth.models import User
from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, Field
from crispy_forms.bootstrap import (PrependedText, PrependedAppendedText, FormActions)
from login.models import User



class RegistrationForm(forms.ModelForm):
     password = forms.CharField(widget=forms.PasswordInput())

     class Meta:
           model = User
           fields = ('username', 'email', 'first_name','last_name','password')
           helper = FormHelper()
           helper.form_method = 'POST'
           helper.add_input(Submit('save', 'save', css_class='btn-primary'))

     class LoginForm(forms.ModelForm):
           password = forms.CharField(widget=forms.PasswordInput())

 class Meta:
    model = User
    fields = ('username', 'password')
@property   
def helper(self):        
    helper = FormHelper()
        helper.form_method = 'POST'
        helper.add_input(Submit('save', 'save', css_class='btn-primary'))
    return helper

Index.html中的弹窗:

<div class="modal fade" id="myModal" tabindex="-1" role="dialog"  aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="myModalLabel">Register </h4>
      </div>
      <div class="modal-body">
   <ul class="nav nav-tabs">
     <li class="active"><a href="#tab1" data-toggle="tab">Login</a></li>
         <li><a href="#tab2" data-toggle="tab">Register</a></li>
     </ul>
        <form action="" method=post"> 
         <div class="tab-content">
           <div class="tab-pane active" id="tab1">
            
    {% crispy loginform %}
    
           </div>
           <div class="tab-pane" id="tab2">
             
    {% crispy regform %}
     
           </div>
         </form>
         </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
        <button type="button" class="btn btn-primary">Submit</button>
      
      </div>
    </div>
  </div>
</div>

尝试用Ajax的弹窗(截取):

<div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
        <button id="register" type="button" class="btn btn-primary">Submit</button>
        <script>
    $('#register').click(function(){
             console.log('am i called');

        $.ajax({
            type: "POST",
            url: "/register/",
            dataType: "json",
            data: $("#login").serialize(),
            success: function(data) {
            alert(data.message);
        }
    });

});
    </script>

用于Ajax请求的登录视图:

def addUser(request):
if request.is_ajax() and request.POST:
    data = {request.POST.get('item')}
    return HttpResponse(json.dumps(data), content_type='application/json') 
else:
raise Http404

根据要求渲染的弹窗HTML:

<!-- Modal --> 
<div class="modal fade" id="myModal" tabindex="-1" role="dialog"   aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="myModalLabel">Register </h4>
      </div>
      <div class="modal-body">
   <ul class="nav nav-tabs">
     <li class="active"><a href="#tab1" data-toggle="tab">Login</a></li>
         <li><a href="#tab2" data-toggle="tab">Register</a></li>
     </ul>
        <form id="login" action="/frontend/register/" method="POST"> 
         <div class="tab-content">
           <div class="tab-pane active" id="tab1">
            
    
用户名* 必填,最多30个字符。可以使用字母、数字和 @/./+/-/_ 字符 密码*
           </div>
    
        
           <div class="tab-pane" id="tab2">
             
    
用户名* 必填,最多30个字符。可以使用字母、数字和 @/./+/-/_ 字符 电子邮件地址 名字 姓氏 密码*
           </div>
         </form>
         </div>
      </div>
    <div class="modal-footer"> 
        <button type="button" class="btn btn-default"   data-dismiss="modal">Cancel</button>
        <button id="register" type="button" class="btn btn-primary">Submit</button>
        <script>
    $('#register').click(function(){
             console.log('am i called');

        $.ajax({
            type: "POST",
            url: "/register/",
            
            data: $(regform).serialize(),
            success: function(data) {
                if (!(data['success'])) {
        
                    $(example_form).replaceWith(data['form_html']);
            }
            else {
        
               $(example_form).find('.success-message').show();
            }
            },
         error: function () {
            $(example_form).find('.error-message').show()
            }
             }
            });

            });
    </script>
        

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

更新Ajax:

<script>
$(document).ready(function() {
var frm = $('#id-registration');
 frm.submit(function (e) {


    $.ajax({
        type: frm.attr('method'), <!-- Get the form's method attribute(defined in login/forms.py -->
        url: frm.attr('action'),  <!-- Get the form's action attribute(defined in login/forms.py -->
        data: $(frm).serialize(),    <!-- package the data -->
        success: function (data) {        <!-- if success return message -->
           if (!(data['success'])) {
            console.log('ifcalled')
            $(frm).replaceWith(data['form_html']); <!-- send replacement form with errors -->
           }
           else{
             console.log('elseCalled')
             $("#div-form").html("Thanks!");
            // $(frm).find('.success-message').show();
            }
        },
        error: function(data) {           <!-- else print error -->
            $(frm).find('.error-message').show()
        }
    });
  e.preventDefault(); <!-- problem is here, validation is all ways false -->

});

});
</script>

更新: 现在表单已经能提交到数据库了。不过表单验证还是不太正常。if/else的判断似乎总是返回假。如果我去掉form.submit(),它就能正常工作并显示表单错误,但页面会刷新。

更新后的views.py:

def addUser(request):

form = RegistrationForm(data=request.POST or None)
if form.is_valid():
    # You could actually save through AJAX and return a success code here
    form.save()
    return {'success': True}

form_html = render_crispy_form(form)
return {'success': False, 'form_html': form_html}

更新后的Forms.py:

class RegistrationForm(forms.ModelForm):
    password = forms.CharField(widget=forms.PasswordInput())
    class Meta:
         model = User
         fields = ('username', 'email', 'first_name','last_name','password')
    def __init__(self, *args, **kwargs):
             super(RegistrationForm, self).__init__(*args, **kwargs)
             self.helper = FormHelper()
             self.helper.form_id = 'id-registration'
             self.helper.form_class = 'blueForms'
             self.helper.form_method = 'post'
             self.helper.form_action = '/register/'
             self.helper.add_input(Submit('submit', 'Submit'))

问题已经解决:

<script type="text/javascript"     src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script type="text/javascript" src="{% static 'js/jquery-validation- 1.11.1/jquery.validate.js' %}"></script>   
<script>
$(document).ready(function () {
  var frm = $('#id-registration');
  $('#id-registration').validate({
  
    rules: {
        username: {required: true},
        email: {required: true},
        password: {required: true}
        
},

 submitHandler: function(){
    $.ajax({//begin
        type: 'POST', <!-- Get the form's method attribute(defined in login/forms.py -->
        url: frm.attr('action'),  <!-- Get the form's action attribute(defined in   login/forms.py -->
        data: $(frm).serialize(),    <!-- package the data -->
        success: function(data){
            $(frm).hide();
    $("#div-form").html("<h3 style='text-align:center;'>Thank you, for Registering!</h3>");
    
        },
        error: function(data) {           <!-- else print error -->
            $("#div-form").html("Failure!");
        }//end error
    });//end ajax

    return false;
    }   
    });   
    });



    </script>

3 个回答

0

我之前也遇到过类似的问题,去掉了 data-dismiss="modal" 这个属性后,问题就解决了。

这虽然没有直接回答你的问题,但可能会帮助到遇到同样问题的人,看到这个页面时能找到解决办法。

0

你有两种选择:

  1. 通过一个HTML的POST请求

<form>标签里放一个<button>按钮。把这个提交按钮的类型改成type="submit",并且设置好表单的属性,添加一个动作(action),同时修正方法(method)里的拼写错误。

  1. 通过一个AJAX请求。

给提交按钮加一个id,然后为这个按钮添加一个点击事件,在这个事件里执行AJAX请求。

<script>
    $('#login').on('click', function (e) {
        // login action
    });
</script>

想了解更多信息,可以查看 http://getbootstrap.com/javascript/#modals-examples

1

首先,你可以打开浏览器的开发者工具(比如在Firefox中使用Firebug)。在“网络”标签下,仔细观察你的POST请求是否被发送出去。

一旦请求发送后,你可以查看请求的内容和响应。这有助于你确认表单是否成功获取了所有输入的数据,或者是否在urls.py文件中遇到了问题。

如果表单提交成功(状态码为200),那么你就可以开始调试你的Django应用了。

撰写回答