Django Ajax ModelForm 向 request.POST 提交一个空表单

Posted

技术标签:

【中文标题】Django Ajax ModelForm 向 request.POST 提交一个空表单【英文标题】:Django Ajax ModelForm submits an empty form to request.POST 【发布时间】:2013-08-11 03:47:31 【问题描述】:

在 django、ajax 和 jquery 方面我有点新手,所以如果我的问题变得微不足道,我提前道歉。

一段时间以来,我一直在摸索这个问题,但我正在尝试使用 ajax 和 jquery 通过 jQuery UI 提供的模式对话框窗口提交 Django ModelForm 表单。我遇到的问题是,表单数据似乎没有传递到请求中,或者我的views.py 文件中的表单对象在解析reqest.POST 对象时遇到问题。无论我何时提交表单,form.is_valid() 都会失败并查看表单错误,我会为表单的每个输入获得“此字段是必需的”。所以不确定我做错了什么,有问题的表单在我尝试使用 ajax 对其进行“模态化”之前就起作用了。

这是我的代码,也许更老练的人可以看到我错过了什么。

forms.py

from django.forms import ModelForm
from artists.views import Artist

class RegistrationForm(ModelForm):
    username = forms.CharField(label=(u'User Name'))
    first_name = forms.CharField(label=(u'First Name'))
    last_name = forms.CharField(label=(u'Last Name'))
    email = forms.EmailField(label=(u'Email'))
    password = forms.CharField(label=(u'Password'),
                               widget=forms.PasswordInput(render_value=False))
    password = forms.CharField(label=(u'Verify Password'),
                               widget=forms.PasswordInput(render_value=False))

    class Meta:
        model = Artist
        exlude = (user, slug, work_email)

views.py

from django.http import HttpResponse
from django.contrib.auth.models import User
from django.shortcut import render
from django.template.defaultfilters import slugify
from django.utils.functional import Promise
from django.utils.encoding import force_text
from django.shortcuts import render

from artists.forms import RegistrationForm
from artists.models import Artist
import json

class LazyEncoder(json.JSONEncoder):
    def default(self, obj):
    if isinstance(obj, Promise):
        return force_text(obj)
    return super(LazyEncoder, self).default(obj)

def ValidateEmail(email):
    from django.core.validators import validate_email
    from django.core.exception import ValidationError
    try:
        validate_email(email)
        return True
    except ValidationError:
        return False

def ArtistRegistration(request):
    form = False

    if request.method == 'POST' and request.is_ajax():
        form = RegistrationForm(request.POST)
        if form.is_Valid():
            is_valid = True
            username = form.cleaned_data['username']
            password = form.cleaned_data['password']
            password1 = form.cleaned_data['password1']
            email = form.cleaned_data['email']
            first_name = form.cleaned_data['first_name'].title()
            last_name = form.cleaned_data['last_name'].title()

            if ValidateEmail(email) is False:
                is_valid = False
                message = "Email entry is invalid."

            if User.objects.filter(username=username).exists():
                is_valid = False
                message = "Username already exists."

            if password != password1:
                is_valid = False
                message = "Passwords do not match."

            if is_valid is False:
                response_dict = "type": "error"
                response_dict["message"] = message
                result = json.dumps(response_dict, cls=LazyEncoder)
                return HttpResponse(result, mimetype='application/json')
            else:
                user = User.objects.create_user)
                    username = username,
                    email = email,
                    password = password,
                    first_name = first_name,
                    last_name = last_name_
                user.save()
                artist = Artist(
                    user = user,
                    first_name = first_name,
                    last_name = last_name,
                    work_email = email,
                    slug = slugify('%s %s' % (first_name, last_name)),
                    department=form.cleaned_data['department'])
                artist.save()

                response_dict = 'status':1, 'type':'success'
                result = json.dumps(response_dict, cls=LazyEncoder)
                return HttpResponse(result, mimetype='application/json')
        else:
            response_dict = 'type': 'error'
            response_dict['message'] = 'form is invalid'
            response_dict['errors'] = json.dumps(form.errors)
            result = json.dumps(response_dict, cls=LazyEncoder)
            return HttpResponse(result, mimetype='application/json')

    else:
        form = RegistrationForm()
        context = 'form' : form
        return render(request, 'register-modal.html', context)

这是我的模态对话框调用的 html: 注册-modal.html

<form action="% url 'modal_registration' %" method="post" id="register_form" name="register_form">
   % csrf_token %
   <table>
      <tbody>
         <tr>
            <th><label for="first_name">First Name:</label></th>
            <td> form.first_name </td>
         </tr>
         <tr>
            <th><label for="last_name">Last Name:</label></th>
            <td> form.last_name </td>
         </tr>
         <tr>
            <th><label for="email">Email:</label></th>
            <td> form.email </td>
         </tr>
         <tr>
            <th><label for="username">Username:</label></th>
            <td> form.username </td>
         </tr>
         <tr>
            <th><label for="password">Password:</label></th>
            <td> form.password </td>
         </tr>
         <tr>
            <th><label for="password1">Verify Pswd:</label></th>
            <td> form.password1 </td>
         </tr>
         <tr>
            <th><label for="department">Department:</label></th>
            <td> form.department </td>
         </tr>
      </tbody>
   </table>
</form>
<span id="registration_error" name="registration_error" style="color: #FF0000;"></span>

最后是进行所有 jquery 和 ajax 调用的 js 文件。 我省略了 csrf 部分,因为它是从 Django 文档中逐字复制的。

注册.js

$(document).ready(function () 
    $.ajaxSetup(traditional: true);

    var $register_dialog = $('#modal_register_div').dialog(
        autoOpen: false,
        title: "User Registration",
        closeOnEscape: true,
        draggable: false, 
        resizable: false,
        modal: true,
        width: 450,
        buttons: 
            "Register": function () 
                var $this = $(this);
                var frm = document.form['register_form'];
                $.ajax(
                    type: frm.method,
                    url: frm.action,
                    data: $('#register_form').serialize(),
                    contentType: "application/json;charset=utf-8",
                    dataType: 'json',
                    success: function(response)
                        if(response['type'] == 'success') 
                            //any extra success functionality goes here
                            $this.dialog("close");
                         else 
                            $("#registration_error").html(response['message']);
                            console.log(response['errors']);
                        
                    ,
                    error: function(xhr, ajaxOptions, thrownError) 
                        alert(thrownError + '\n' + xhr.status + '\n' + ajaxOptions)
                    
                );
                return false;
            
        
    );

    $('#register_artist').live("click", function () 
        $.ajax(
            type: 'get',
            dataType: 'html',
            url: '/register/'
            data: ,
            success: function(response)
                $register_dialog.empty().html(response).dialog('open');
            
        );
    );
);

模态对话框绑定到我的 django 页面的基本模板页面上的隐藏 div,并且 js 脚本加载在同一页面上。通过单击空 href 链接调用该对话框。无论如何,如果有人能看到我做错了什么,您的意见将不胜感激。

谢谢!

【问题讨论】:

$('#register_form').serialize()的内容是什么? 【参考方案1】:

弄清楚我的愚蠢之处。在我的 ajax 调用中,我将我的内容类型定义为: contentType: 'application/json;charset=utf-8'

当它应该是以下情况时: contentType: 'application/x-www-form-urlencoded;charset=utf-8'

在查看了与注册表单相比有效的登录表单的标题数据后,我意识到,在我的登录表单中,数据是通过“Form_Data”传递给请求的,而我的注册表单正在传递作为“Request_Payload”。做出改变后,一切都像魅力一样。

【讨论】:

谢谢,我是一个堆栈菜鸟,所以我忽略了这样做。

以上是关于Django Ajax ModelForm 向 request.POST 提交一个空表单的主要内容,如果未能解决你的问题,请参考以下文章

从Django中基于类的通用视图向ModelForm发送request.user对象

AJAX向Django后端提交POST请求

Django(Form,ModelForm)

ajax向Django前后端提交请求和CSRF跨站请求伪造

django - 使用 FormView 和 ModelForm 更新模型

ModelForm 的 Django 编辑模板未填充值