2013-03-09 70 views
1

对此感到沮丧了几天,并想知道是否有人可以提供帮助。我是新来的Ajax,并尝试从登录表单发布数据以便登录到Django(Django Userena)。但是,当我尝试发布数据时,alert()将数据中的错误显示为[对象对象]。我甚至无法看到网络错误代码,因为POST在运行之前被取消。将Ajax POST表单发送到Django数据问题

有没有办法发送数据,而不是我认为它发送的整个JSON数组,还是我需要在Django视图后端解析它?明智地完成这个代码的最好方法是什么?非常感谢你!

下面是相关代码:

Ajax代码:对的Index.html

$('#login').submit(function(){ 

    $.ajax({ 

     url: 'http://127.0.0.1:8000/accounts/signin/', 
     type: 'POST', 
     data: { 
      csrfmiddlewaretoken: '{{csrf_token}}', 
      identification: $("#id_identification").val(), 
      password: $("#id_password").val(), 
      }, 
     success: function() { 
      alert('Test'); 
      $('#datadisplay').append("<h2>It worked</h2>"); 
     }, 
     error: function(errorThrown){ 
      console.log(errorThrown); 
      alert('Error'); 
      alert(errorThrown); 
     } 
    }); 
}); 

<form name="login" id="login" action=""> 
    <fieldset> 
      <label for="id_identification">Email or username</label> 
      <input class="required" id="id_identification" maxlength="75" name="identification" type="text" /> 

      <label for="id_password">Password</label> 
      <input class="required" id="id_password" name="password" type="password" /> 

      <input type="submit" name="submit" class="loginbutton" value="Login" /> 
     </fieldset> 
    </form> 

从Django的Userena

views.py
@secure_required 
def signin(request, auth_form=AuthenticationForm, 
      template_name='userena/signin_form.html', 
      redirect_field_name=REDIRECT_FIELD_NAME, 
      redirect_signin_function=signin_redirect, extra_context=None): 
    """ 
    Signin using email or username with password. 

    Signs a user in by combining email/username with password. If the 
    combination is correct and the user :func:`is_active` the 
    :func:`redirect_signin_function` is called with the arguments 
    ``REDIRECT_FIELD_NAME`` and an instance of the :class:`User` who is is 
    trying the login. The returned value of the function will be the URL that 
    is redirected to. 

    A user can also select to be remembered for ``USERENA_REMEMBER_DAYS``. 

    :param auth_form: 
     Form to use for signing the user in. Defaults to the 
     :class:`AuthenticationForm` supplied by userena. 

    :param template_name: 
     String defining the name of the template to use. Defaults to 
     ``userena/signin_form.html``. 

    :param redirect_field_name: 
     Form field name which contains the value for a redirect to the 
     succeeding page. Defaults to ``next`` and is set in 
     ``REDIRECT_FIELD_NAME`` setting. 

    :param redirect_signin_function: 
     Function which handles the redirect. This functions gets the value of 
     ``REDIRECT_FIELD_NAME`` and the :class:`User` who has logged in. It 
     must return a string which specifies the URI to redirect to. 

    :param extra_context: 
     A dictionary containing extra variables that should be passed to the 
     rendered template. The ``form`` key is always the ``auth_form``. 

    **Context** 

    ``form`` 
     Form used for authentication supplied by ``auth_form``. 

    """ 
    form = auth_form() 

    if request.method == 'POST': 
     form = auth_form(request.POST, request.FILES) 
     if form.is_valid(): 
      #identification, password, remember_me = (form.cleaned_data['identification'], 
                #form.cleaned_data['password'], 
                #form.cleaned_data['remember_me']) 
      identification, password = (form.cleaned_data['identification'], form.cleaned_data['password'])  

      user = authenticate(identification=identification, 
           password=password) 
      if user.is_active: 
       login(request, user) 
       if remember_me: 
        request.session.set_expiry(userena_settings.USERENA_REMEMBER_ME_DAYS[1] * 86400) 
       else: request.session.set_expiry(0) 

       if userena_settings.USERENA_USE_MESSAGES: 
        messages.success(request, _('You have been signed in.'), 
            fail_silently=True) 

       # Whereto now? 
       redirect_to = redirect_signin_function(
        request.REQUEST.get(redirect_field_name), user) 
       return HttpResponseRedirect(redirect_to) 
      else: 
       return redirect(reverse('userena_disabled', 
             kwargs={'username': user.username})) 

    if not extra_context: extra_context = dict() 
    extra_context.update({ 
     'form': form, 
     'next': request.REQUEST.get(redirect_field_name), 
    }) 
    return ExtraContextTemplateView.as_view(template_name=template_name, 
              extra_context=extra_context)(request) 

AuthenticationForm

class AuthenticationForm(forms.Form): 
    """ 
    A custom form where the identification can be a e-mail address or username. 

    """ 
    identification = identification_field_factory(_(u"Email or username"), 
                _(u"Either supply us with your email or username.")) 
    password = forms.CharField(label=_("Password"), 
           widget=forms.PasswordInput(attrs=attrs_dict, render_value=False)) 
    remember_me = forms.BooleanField(widget=forms.CheckboxInput(), 
            required=False, 
            label=_(u'Remember me for %(days)s') % {'days': _(userena_settings.USERENA_REMEMBER_ME_DAYS[0])}) 

    def __init__(self, *args, **kwargs): 
     """ A custom init because we need to change the label if no usernames is used """ 
     super(AuthenticationForm, self).__init__(*args, **kwargs) 
     # Dirty hack, somehow the label doesn't get translated without declaring 
     # it again here. 
     self.fields['remember_me'].label = _(u'Remember me for %(days)s') % {'days': _(userena_settings.USERENA_REMEMBER_ME_DAYS[0])} 
     if userena_settings.USERENA_WITHOUT_USERNAMES: 
      self.fields['identification'] = identification_field_factory(_(u"Email"), 
                     _(u"Please supply your email.")) 

    def clean(self): 
     """ 
     Checks for the identification and password. 

     If the combination can't be found will raise an invalid sign in error. 

     """ 
     identification = self.cleaned_data.get('identification') 
     password = self.cleaned_data.get('password') 

     if identification and password: 
      user = authenticate(identification=identification, password=password) 
      if user is None: 
       raise forms.ValidationError(_(u"Please enter a correct username or email and password. Note that both fields are case-sensitive.")) 
     return self.cleaned_data 
+1

我没有看到任何代码易受POST POST JSON数组影响。 AJAX请求的响应代码是什么?也许'{{csrf_token}}'是空的? – jpic 2013-03-09 23:01:58

+0

您可以尝试使用@csrf_exempt临时删除csrf验证,以查看是否还有其他问题 – 2013-03-09 23:07:12

+0

感谢您的回复。我无法获取响应代码,因为它在完成之前出错。上面代码的控制台打印出“Object {readyState:0,getResponseHeader:function,getAllResponseHeaders:function,set RequestHeader:function,overrideMimeType:function ...}”,但是一旦我关闭了最后一个对话框,它就会退出并清除控制台。 \t 当窗体不是通过Django显示而是外部html窗体显示时,如何将csrf_token放入窗体中? – Jack 2013-03-09 23:08:39

回答

1

这些都是错误的(不是全部,我想有更多的)我看到,当我测试你的代码:

  1. 你怎么可以登录,如果你没有在您的模板中使用您的AuthenticationForm()。你在表格中的代码是不同的。
  2. 您没有在您的表单中放入method =“POST”,这会导致GET响应而不是POST。
  3. 你忘了把{%csrf_token%}在你的模板形式
  4. 在你views.py,用户认证=(标识=识别,密码=密码)必须用户认证=(用户名=识别,密码=密码)
  5. 在你forms.py,用户认证=(标识=识别,密码=密码)必须用户认证=(用户名=识别,密码=密码)
  6. 你的AJAX代码没有效果,这就是为什么你可以没有得到抛出的错误。我认为你的ajax中缺少一些东西。
  7. 要获得抛出的错误的详细信息:

    error: function(ts){ 
        //console.log(errorThrown); 
        //alert('Error'); 
        alert(ts.responseText); 
        } 
    
  8. 你的Ajax数据必须':

    data: { 
        'csrfmiddlewaretoken': '{{csrf_token}}', 
        'identification': $("#id_identification").val(), 
        'password': $("#id_password").val(), 
        }, 
    
  9. 你不必详细阐述您的网址像这样的

    url: 'http://127.0.0.1:8000/accounts/signin/', 
    

    这将导致

    "http://127.0.0.1:8000/http://127.0.0.1:8000/accounts/signin/" 
    

    它必须是

    url: '/accounts/signin/', 
    

    ,不也忘了把

    contentType: "application/json;charset=utf-8", 
    dataType: "json", 
    

有更多的错误,到现在为止我无法成功登录。

+0

非常感谢您的帮助。我正在处理这个问题,现在发布POST没有错误,但我认为它没有做任何事情,页面只是引用了没有发送的数据。我的目标是用Django作为后端制作移动应用程序。随着PhoneGap的前端只需要HTML/CSS/JS ** **,所以没有Django模板和Django标签没有意​​义。你知道是否有一个更简单的解决方案来实现我的目标,即让用户登录/注册?我认为TastyPie可能是最好的选择,但是我尝试了这一点,但是也找不到它。任何见解都会非常有帮助。谢谢! – Jack 2013-03-10 03:34:36

+0

我不知道任何移动设备。我也从来没有使用TastyPie。如果我能得到一个信息,我会马上告诉你:) – catherine 2013-03-10 07:56:10