1

I have just started Django and what I was trying to implement $http.post method of angular to post form data to my Django database,and my further plan was to update the view to display the results without page refresh.so what i thought to post data in django db and then my view function will return a jsonresponse,of that posted data which i can use to update the view using $http.get method.

But the problem is occuring with me is whenever i post data it is not able to post the data and returning an empty json response.

Here is my codes which i am working on:-

urls.py

from django.conf.urls import url
from . import views
app_name='demo'
urlpatterns=[
    url(r'^$',views.index,name="index"),
    url(r'^add_card/$',views.add_card,name="add_card")

]

views.py

from django.shortcuts import render
from django.http import HttpResponse,JsonResponse
from .forms import CardForm
from .models import Card
# Create your views here.

def add_card(request):
    saved = False
    if request.method == 'POST':
        #print('hi')
        form = CardForm(request.POST)
        #print('hi')
        if form.is_valid():
            #print('hi')
            card = Card()
            #print('hi')
            card.content = form.cleaned_data['content']
            #print('hi')
            saved = True
            card.save()
            #print('hi')
        return JsonResponse({'body':list(q.content for q in Card.objects.order_by('-id')[:15])})

    else:
        return HttpResponse(
            json.dumps({"nothing to see": "this isn't happening"}),
            content_type="application/json"
        )

def index(request):
    return render(request,'demo/index.html',{'form':CardForm()})

controller.js

var nameSpace = angular.module("ajax", ['ngCookies']);

nameSpace.controller("MyFormCtrl", ['$scope', '$http', '$cookies',
function ($scope, $http, $cookies) {
    $http.defaults.headers.post['Content-Type'] = 'application/json';
    // To send the csrf code.
    $http.defaults.headers.post['X-CSRFToken'] = $cookies.get('csrftoken');

    // This function is called when the form is submitted.
    $scope.submit = function ($event) {
        // Prevent page reload.
        $event.preventDefault();
        // Send the data.
        var in_data = jQuery.param({'content': $scope.card.content,'csrfmiddlewaretoken': $cookies.csrftoken});
        $http.post('add_card/', in_data)
          .then(function(json) {
            // Reset the form in case of success.
            console.log(json.data);
            $scope.card = angular.copy({});
        });
    }
 }]);

My models.py:-

from django.db import models

# Create your models here.
class Card(models.Model):
    content = models.TextField()
    date = models.DateTimeField(auto_now_add=True)
    def __str__(self):
        return self.content

My forms.py-

from django import forms
from .models import Card

class CardForm(forms.ModelForm):
    class Meta:
        model = Card
        fields = ['content']
8
  • You are returning a JsonResponse with {'body': ... } but in you Angular code you are logging json.data. Try replacing body with data to see if you get any response. Commented Apr 18, 2017 at 13:38
  • If i change data with body the console is printing undefined... actually the json which i get on success response is like this Object {data: Object, status: 200, config: Object, statusText: "OK", headers: function},in which body resides in data part that's why i logged json.data there @dentemm Commented Apr 18, 2017 at 13:50
  • Okay, and if you log json.data.body? Commented Apr 18, 2017 at 13:57
  • Ok that's fine But my main problem is that my view.py code is not able to post the data in my database,so my first purpose is to get that data saved then i will think about the json @dentemm,Can You please suggest me some edits in my view.py file that will be a great help thanks. Commented Apr 18, 2017 at 14:01
  • Okay I didn't understand, I will try to create an answer Commented Apr 18, 2017 at 14:05

1 Answer 1

2

You have some problems in your view.py code.

  1. You need to create a new object in your database from the request data
  2. You need to return the new data as a response

    if form.is_valid():
        new_content = form.cleaned_data['content']
        card = Card.objects.create(content=new_content)
        return JsonResponse(
               list(Card.objects.all().order_by('-id').values('content')[:15]),
               safe=False
        )
    

    That should return a list of the content value of your first 15 objects in your Card table after creating a new object in that table by the content provided, IF your form is valid.

  3. Also your CardForm should be defined as follows:

    class CardForm(forms.ModelForm):
        class Meta:
            model = Card
            fields = ('content',)
    
  4. Finally, your $http.post call is asynchronous, which means that when the .then is reached, there is a probability (almost a certainty) that the post request has not been resolved yet, thus your json.data is empty. To solve this problem:

    $http.post('add_card/', in_data)
        .then((json) => {
            // Reset the form in case of success.
            console.log(json.data);
            $scope.card = angular.copy({});
    });
    

    A far better read and solutions on the asynchronous-to-synchronous calls are: ES6 Promises - Calling synchronous functions within promise chain, How do you synchronously resolve a chain of es6 promises? and Synchronous or Sequential fetch in Service Worker

Good luck :)

Sign up to request clarification or add additional context in comments.

8 Comments

Sir, I applied the changes but it is still returning an empty json and the the posted data are not being saved @john Moutafis
Can you provide your Card model from the models.py in your question as an edit?
I have edited the JsonResponse, and a possible problem in your form, have a look
it is giving syntax error for safe=False @john Moutafis and also if i remove it it gives another Typeerror of unhashable list
My fault, I forgot the {} from the previous edit, I reedited the answer
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.