2

I tried this code to save my JSON data to my model that is Mvouchar. But getting this error. I easily get data through cmd but I tried to save this in my model then I get the error, why this happens, I think am doing some minor mistake but can't catch please help if u get my problem

#views.py
@csrf_exempt
def jsdata(request):
    table_data = json.loads(request.POST.get('MyData'))
    print(table_data)
    for data in table_data:
     b_no = request.POST['billno']
     b_details = request.POST['billdetails']
     at = request.POST['amount2']
     record = Mvouchar(bill_no = data.b_no, bill_details = data.b_details,am=data.at)
    record.save()
    return render(request, 'cheque/mvouchar.html', {'msg': 'Data Saved.'})
    
#models.py

class Mvouchar(models.Model):
 related = models.ForeignKey(Signs, on_delete=models.CASCADE, null=True, blank=True)
 bill_no = models.CharField(max_length=80, null=True, blank=True)
 bill_details = models.CharField(max_length=1000, null=True, blank=True)
 am = models.CharField(max_length=30, null=True, blank=True)
 vouchar_no = models.CharField(max_length=1000, null=True, blank=True)
  
#urls.py

url(r'jsondata/$', views.jsdata, name='jsondata'),

#script
<script>
$("#btnjson").click(function () {
   var array1 = [];
     $("tbody tr").each(function () {
                        var firstTableData = {};
                        firstTableData.BillNo = $(this).find('td').eq(0).text();
                        firstTableData.BillDetails = $(this).find('td').eq(1).text();
                        firstTableData.Amount = $(this).find('td').eq(2).text();
                        array1.push(firstTableData);
                    //}
                }); 
    alert(JSON.stringify(array1));
     $.ajax({
    type: "POST",
    url: "/jsondata/",
    dataType: 'json',
    data: {MyData: JSON.stringify(array1)},
    success: function(msg){
                alert(msg);
            }
        });
        return false;
    } );
   });
</script>
  • Can you post `table_data` that is printing in your console. – Pankaj Sharma Oct 25 '18 at 08:25
  • This error probably occurs when the key not present in request data. – a_k_v Oct 25 '18 at 08:26
  • please see my question now i insert image with print table_data – monika choudhary Oct 25 '18 at 08:31
  • In this case, it really is uppercase letters as I mentioned in my answer - python dictionary keys are case sensitive. Your dictionary contains `BillNo` but you query for `billno`. – ingofreyer Oct 25 '18 at 08:32
  • 1
    From your ajax you are sending just one array MyData which contains your json string. How do you expect to get `request.POST['billno']` in your view. It doesn't exists, you never sent it. I think in your ajax you should post `data: JSON.stringify(array1)`, there is no need to put the json in another object. – Vaibhav Vishal Oct 25 '18 at 08:33
  • there is another good point - you should try to get `data['BillNo']` instead of `request.POST['billno']` – ingofreyer Oct 25 '18 at 08:34
  • yeah that would work too, but whats the point of posting json data inside another object, hence making it practically json inside json – Vaibhav Vishal Oct 25 '18 at 08:36
  • hey @VaibhavVishal i dnt understand what u want to say i know i missing something but could not find out – monika choudhary Oct 25 '18 at 08:37
  • Your code should work with the instructions I provided in my answer. Vaibhav just brings up two excellent points (the wrong element to query - see my answer for an expanded explanation) and a possibly easier way to send the data (of which I am not completely sure if I agree - but it is definitely worth a try) – ingofreyer Oct 25 '18 at 08:41
  • 1
    nvm i see you are sending an array to create multiple objects, so the way you are sending json is alright. I was thinking you are going to create just one object. – Vaibhav Vishal Oct 25 '18 at 08:49
  • :-) Then I see why I was confused with that suggestion. @monikachoudhary - I edited my answer to include a code snippet that should solve your issues. – ingofreyer Oct 25 '18 at 08:50
  • I also found another issue: There seems to be one space missing before the `record.save()` line - this may be a copy & paste error but it for sure is an indentation error. – ingofreyer Oct 25 '18 at 08:53
  • i want to save these array value in three different filleds that's why am doing this now i edited my code and get following error plz check question for trace – monika choudhary Oct 25 '18 at 08:53
  • no its my notepad ++ problem that getting like that – monika choudhary Oct 25 '18 at 08:54
  • @monikachoudharySorry, my bad, I overlooked that mistake - I corrected my example code accordingly (basically, you could either do the lookup in `data` directly or use the variables (which is what I opted for). – ingofreyer Oct 25 '18 at 09:08

4 Answers4

1
from django.http import JsonResponse
    def jsdata(request):
        table_data = json.loads(request.POST.get('MyData'))
        # print(table_data)
        r_data = {
            'success': True,
        }
        for data in table_data:
            # Since you are just creating objects you don't need to save created object in a variable.
            try:
                Mvouchar.objects.create(bill_no = data['BillNo'], bill_details=data['BillDetails'],at=data['Amount'])
            except:
                r_data['success'] = False

        # IMO Views responding to ajax requests should send JsonResponse
        if r_data['success']:
            r_data['msg'] = 'Data Saved'
        else:
            r_data['msg'] = 'Not all Data Saved'
        return JsonResponse(r_data)
Vaibhav Vishal
  • 6,576
  • 7
  • 27
  • 48
0

A KeyError is usually thrown when you look up a value for a key in a dictionary that does not exist. You could either provide a default value or check the existence of the key before you do the lookup.

request.POST.get('billno', 'default_value')

For more information about querying a dictionary with default values, see this helpful StackOverflow answer

The line above as such will not work, since there are other issues in this code besides the key not existing with only lowercase letters (see below).

Looking at the code I expect the key to not exist either because it has not been sent or because it may contain uppercase letters.

As it has been pointed out in the comments to your question, not only are you querying for billno (only lowercase letters) while the key you send has uppercase letters (BillNo), but you also embed it into another dictionary MyData - you need to change your query from request.POST['billno'] to data['BillNo'] (the same goes for all the other values you are trying to extract).

The correct query would thus look like this:

for data in table_data:
    b_no = data['BillNo']
    b_details = data['BillDetails']
    at = data['Amount']
    record = Mvouchar(bill_no = b_no, bill_details = b_details,am=at)
    record.save()
ingofreyer
  • 1,086
  • 15
  • 27
0

This error probably occurs when the key not present in request data. By changing

b_no = request.POST['billno'] 

to

b_no = request.POST.get('BillNo').

solve throwing this exception. Even if data not present it returns None. Or can handle it by add try.except block.

try:
    b_no = request.POST['billno'] 
except KeyError:
    pass

And in your code, you call every dict key in lower case form and amount key as amount2. Change that to Amount

a_k_v
  • 1,558
  • 7
  • 18
0

If your are storing data in table_data (table_data = request.POST.get('MyData')) then use table_data to store it in models.

Your data is in dictionary form so need to call values by its keys. like -

@csrf_exempt
def jsdata(request):
    table_data = json.loads(request.POST.get('MyData'))
    print(table_data)
    for data in table_data:
        b_no = data.get('BillNo')
        b_details = data.get('BillDetails')
        at = data.get('Amount')
        record = Mvouchar(bill_no = b_no , bill_details = b_details ,am=at )
       record.save()
    return render(request, 'cheque/mvouchar.html', {'msg': 'Data Saved.'})

Try this and tell me if any error occurs.

Pankaj Sharma
  • 2,185
  • 2
  • 24
  • 50