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

kan*_*Red 4 django ajax jquery django-forms

我对 django、ajax 和 jquery 有点陌生,所以如果我的问题微不足道,我会提前道歉。

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

这是我的代码,也许经验丰富的人可以看到我错过了什么。

表格.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)
Run Code Online (Sandbox Code Playgroud)

视图.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)
Run Code Online (Sandbox Code Playgroud)

这是我的模态对话框调用的 html: register-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>
Run Code Online (Sandbox Code Playgroud)

最后这里是进行所有 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');
            }
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

kan*_*Red 5

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

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

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