Ajax成功调用显示div与表单数据

时间:2013-07-26 13:55:18

标签: python django python-2.7 django-models django-forms

views.py

def index(request):
    """"""""""""""
    registerform = UserRegisterForm(request.POST)
    createprofileform = UserCreateProfileForm(request.POST)                            
    if registerform.is_valid() and createprofileform.is_valid():               
        result = registerform.save(commit=False)
        result.set_password(request.POST['password'])        #set member password
        result.username = username               
        result.save()
        member.user_id = user.id
        member.member_id = result.id
        member.save()                                        #new member registration
        member_profile = UserProfile.objects.get(user=result.id)
        createprofileform = UserCreateProfileForm(request.POST, instance=member_profile)
        createprofileform.save()                             #create member profile                
        createprofileform = UserCreateProfileForm()
        member_save_msg = 'New member has been added.' 
        """"""""""""
    return render(request,'index.html',{ 'registerform': registerform,'createprofile': createprofileform,})

的index.html

{% block main-content %}
<table width="98%" border="0" style="margin-left:0.7%;" cellpadding="0" cellspacing="0" id="rounded_table">
    <tr >
         <td width="50%">Main Account Holder</td><td width="50%">Authorised Reporters</td>
    </tr>
     <tr id="main_account">
          <td width="50%">All data related to main account holder comes here</td>
     </tr>
     <tr id="authorised_reporter">
          <td  width="100%" colspan="2">
           <div id="authorisedreporter" {% if not registerform.errors %}style="display:none"{% endif %}>
                <form method="post" action="." id="reporter-form">{% csrf_token %}
                <table  width="100%">
                  <tr>
                     <td style="width:100px;">First name:</td><td>{{registerform.first_name}}</td>
                  </tr>
                  <tr>
                     <td>Last name:</td><td>{{registerform.last_name}} </td>
                  </tr>
                         """"""other form fields""""""""
                  <tr>
                     <td colspan=2""><p align="right"><button type="submit" title="Save" >Save <img src="{{ STATIC_URL }}images/button-icon-ir-fwd.png" width="12" height="17" alt="" /></button></p>
                     </td>
                  </tr>
                  </table></form>
</table>
{%endblock%}

上述views.py和index.html用于保存新用户条目。

我的html模板分为2个部分,主要帐户持有人选项卡和授权记者选项卡。主要帐户持有人选项卡用于保存个人资料信息,授权记者选项卡用于创建新用户。页面加载主帐户持有人选项卡将处于活动状态如果选择了用户选项卡,则会隐藏主帐户持有人选项卡。保存用户后,将以下面的格式显示用户详细信息。

{% for list in member_list %}
       <tr class="ir-shade"> 
        <td style="width:120px;"><span><input type="submit" name="delete" value="{{list.0.id}}" class="delete_reporter" /></span><button> id="{{ list.0.id }}" class="openDiv">{{list.0.first_name|title}} {{list.0.last_name}}</button></td>
       <td style="width:410px;"> {{list.0.email}} {{list.1.phone_daytime}} {{list.1.phone_mobile}}</td>
       </tr>
    {% endfor %}

我真正想要的是点击<button> id="{{ list.0.id }}" class="openDiv">{{list.0.first_name|title}} {{list.0.last_name}}</button>已保存的用户数据应显示在可编辑模式的相同字段中。我在按钮中传递用户ID。单击按钮,与用户ID相关的数据应显示在可编辑模式。

JS:

   $('.openDiv').click(function () {              
    var id = $(this).attr('id');  
    var csrf_token = $("#csrf_token").val();
    $.ajax({ 
       data:{
            csrfmiddlewaretoken: ('{{csrf_token}}'),                          
            id:id,                
            },
    type:'POST',
    url: '/setting/save-reporter/',
    success: function(data) {
        $('#authorisedreporter').html(data);
    }
  });
 });

下面的views.py和html是为了显示保存的表单实例而编写的。现在我可以显示已保存的表单实例,我将实例加载到authorisedreporter div中(请检入js和index.html)。这时候如果i kit保存,它正在创建新记录,它正在调用与index方法相关的views.py。我想更新而不保存记录。

save_reporter.html

<form method="post" action="." id="{{ id }}">
    {% csrf_token %}
    <table  width="100%">
        <tr>
            <td style="width:100px;">First name:</td><td>{{form.first_name}}</td>
        </tr>
        <tr>
            <td>Last name:</td><td>{{form.last_name}}</td>
        </tr>
        <tr>
            <td>Daytime phone:</td><td>{{profile.phone_daytime}}</td>
        </tr>
        <tr>
            <td>Mobile phone:</td><td>{{profile.phone_mobile}}</td>
        </tr>
        <tr>
            <td>Email:</td><td>{{form.email}}</td>
        </tr>
        <tr>
            <td>Password</td><td>{{form.password}}</td>
        </tr>
        <tr>
           <td colspan=2"<p align="right">{% include "buttons/save.html" %}</p></td>
        </tr></table></form>

views.py

def save_reporter(request):
    user = request.user
    id = request.POST.get('id')
    user = User.objects.get(pk =id)
    userprofile = UserProfile.objects.get(user=user.id)
    form = ReporterRegisterForm(instance=user)
    profileform = ProfilecontactForm(instance=userprofile)               
    return render(request, 'setting/save_reporter.html',
                   {'form': form,
                    'id':id,
                     'profile':profileform
                    })

我已经解释了我面临的当前问题,请帮助我这样做。谢谢

3 个答案:

答案 0 :(得分:3)

让我分析一下你的JS代码,因为我可以看到几个错误/错误:

$('.openDiv').click(function (e) {       
    e.preventDefault();

    // where is following data taken from? At the point you click the .openDiv link, the form doesn't have any data yet so all of them will be empty string ''
    var csrf_token = $("#csrf_token").val();
    var id =  $(this).closest('td').attr('id');
    var firstname = $("#"+id).find('#id_first_name').val();
    var lastname = $("#"+id).find('#id_last_name').val();
    var phonedaytime = $("#"+id).find('#id_phone_daytime').val(); 
    var phonemobile = $("#"+id).find('#id_phone_mobile').val();
    var email = $("#"+id).find('#id_email').val();

    // do you use AJAX to get the form or use it to save the form?
    $.ajax({ 
        data: $(this).serialize(), // this is wrong, $(this) is the link object, not a form
        type:'POST',
        url: '/setting/save-reporter/',
        success: function(data) {
            $('#authorisedreporter').html(data);
            $('#authorisedreporter').show();
        }
   });
});

好的据我所知,点击链接后,您正在使用AJAX向Django视图发送请求以获取正确的实例化表单。所以你应该:

首先,简化您的JS代码:

$('.openDiv').click(function (e) {       
    e.preventDefault();
    var this_id =  $(this).closest('td').attr('id'); // get the user ID, since that's all you need
    console.log(this_id); // making sure that you get the right ID
    $.ajax({ 
        data: { id: this_id },
        type: 'POST',
        url: '/setting/fetch-reporter-form/',
        success: function(data) {
            $('#authorisedreporter').html(data);
            $('#authorisedreporter').show();
        }
   });
});

接下来,将旧视图拆分为多个视图以关注其需要执行的操作(注意:您可以保留现在的index视图):

def fetch_reporter_form(request):
    ''' Change your save_reporter view name to this view '''
    registerform = UserRegisterForm()

    if request.method == 'POST':
        id = request.POST.get('id', None)
        if id:
            user = get_object_or_404(pk=user.id)
            userprofile = UserProfile.objects.get(user=user)
            registerform = UserRegisterForm(request.POST, instance=user)
            return render(request, 'setting/register_form.html', {
                'user_id': id
                'registerform':registerform
            })
        else:
            return HttpResponse('Request does not contain any ID')
    else:
        return HttpResponse('Request is not POST')

def update_reporter(request):
    ''' This function is for update the reporter '''
    registerform = UserRegisterForm()

    if request.method == 'POST':
    id = request.POST.get('id', None)
        if id:
            user = get_object_or_404(pk=user.id)
            userprofile = UserProfile.objects.get(user=user)
            registerform = UserRegisterForm(request.POST, instance=user)
            if registerform.is_valid():
                result = registerform.save(commit=False)

                # saving code here ...
                return HttpResponse('Success')
        else:
            return HttpResponse('Request does not contain any ID')
    else:
        return HttpResponse('Request is not POST')

你可以看到这里有两个功能:1用于从AJAX中获取正确的表单,另一个用于通过普通表单提交保存数​​据。当然你应该相应地制作urls.py,例如:

urlpatterns = patterns('',
    # ... your code ...
    url(r'^setting/fetch-reporter-form/$', 'yourapp.views.fetch_reporter_form'),
    url(r'^setting/update-reporter/$', 'yourapp.views.update_reporter'),
)

您可能还会注意到,您应该制作一个新模板setting/register_form.html,其中仅包含您的注册表单HTML(注意:您需要一个隐藏的id字段,该字段由上面的fetch_reporter_form视图返回确定表格):

<form method="post" action="/setting/update-reporter" id="reporter-form">
    {% csrf_token %}
    <input type="hidden" name="id" value="{{ user_id }}" />
    <!-- your code here -->
</form>

所以流程是:

  1. 您转到index视图。正常情况下有几种形式可以保存新记者等。
  2. 点击.openDiv按钮。它会将上面的AJAX请求发送到fetch_reporter_form以获取正确的表单。 (此时您的代码工作正常)
  3. 您点击该表单上的保存按钮,它会将更新的数据(通过POST)提交到update_report视图并更新记者。
  4. 我只是想给你一个基本的想法。剩下的很简单,所以我猜你可以轻松继续。希望它有所帮助!

答案 1 :(得分:1)

让我恢复你正在做的事情:

$.ajax({ 
    data:{
        /* ... */
    },
    type:'POST',
    url: '/report/save_reporter/',
    success: function() {
        return true;
    }
});

在此设置Ajax异步查询以将数据发布到服务器。当查询到达服务器时,如果它没有崩溃,则调用success:回调并且javascript什么都不做(return true;)。

$('#authorisedreporter').show();

在此,您将在异步Ajax查询结束之前显示HTML节点 (成功或失败)。要在Ajax查询完成后显示元素,请将此代码放在success:error:回调中。

最后,如果您算上(){},您会看到$('#authorisedreporter').show();超出了点击回调。因此,如果它不在文档就绪回调中,则无效。

所以正确的Javascript代码应该是(我认为):

$('.openDiv').click(function (e) {    
    e.preventDefault();          
    var id = $(this).attr('id');  
    var firstname = $("#"+id).find('#id_first_name').val();    
    var phonemobile = $("#"+id).find('id_phone_mobile').val();    
    $.ajax({ 
        data:{
            csrfmiddlewaretoken: csrf_token,
            edit_reporter:true,
            id:id,
            first_name:firstname,               
            phone_mobile:phonemobile,
        },
        type:'POST',
        url: '/report/save_reporter/',
        success: function() {
            $('#authorisedreporter').show();
        }
   });
});

修改

关于您的view.py,您保存了UserProfile但不向客户端浏览器返回任何内容。什么都没有。

def save_reporter(request):
    user=User.objects.get(user=user) # you should use django.shortcuts.get_object_or_404
    userprofile = Userprofile.objects.get(user=user) # same comment
    if request.method == 'POST':
        registerform = UserRegisterForm(request.POST,instance=user)
        createprofileform = UserCreateProfileForm(request.POST,instance=userprofile)
        # you create 2 forms above, but don't use them. Is it normal ?!
        # you should do loops "if registerform .valid(): ... else: ..." and use it. Same for the 2nd form
        if 'edit_reporter' in request.POST:
            first_name=request.POST.get('first_name') # can be None
            phone_mobile = request.POST.get('phone_mobile') # can be None      
            user = User.objects.get(pk=user)
            user.first_name = first_name            
            user.save() # put it inside a try/except statment
            userprofile = UserProfile.objects.get(pk=user) # use get_or_404
            userprofile.phone_mobile = phone_mobile 
            userprofile.save() # put it inside a try/except statment
    return HttpResponse() # this returns an empty html page, do you want to return the form here ?

答案 2 :(得分:0)

检查服务器是否有任何错误消息:

$.ajax({ 
    // ...
    error: function(err) {
        console.log(err);
    }

});

修改

提交表单时不传递用户ID。尝试做类似的事情:

<form ...>
   <!-- //.. -->
   {{ form.id.as_hidden }}
</form>