문제

I am trying to fetch JSON response from my Django App but response is not working :

Here is my views.py :

import json
import traceback
from django.http import HttpResponse
from django.template import Context,loader
from django.template import RequestContext
from django.shortcuts import render_to_response
from eScraperInterfaceApp.eScraperUtils import eScraperUtils 

#------------------------------------------------------------------------------

def renderError(message):
    """
        This function displays error message
    """    
    t = loader.get_template("error.html")                
    c = Context({ 'Message':message})
    return HttpResponse(t.render(c))

def index(request,template = 'index.html',
                  page_template = 'index_page.html' ):
    """
        This function handles request for index page 
    """

    try:        
        context = {}
        contextList = []
        utilsOBJ = eScraperUtils()        
        q = {"size" : 300000,
             "query" :{ "match_all" : { "boost" : 1.2 }}}
        results = utilsOBJ.search(q)       

        for i in results['hits']['hits']:

            contextDict = i['_source']            
            contextDict['image_paths'] = json.loads(contextDict['image_paths'])
            contextList.append(contextDict)            

        context.update({'contextList':contextList,'page_template': page_template})     

        if request.is_ajax():    # override the template and use the 'page' style instead.
            template = page_template

        return render_to_response(
            template, context, context_instance=RequestContext(request) )

    except :        
        return renderError('%s' % (traceback.format_exc()))

def search (request,template = 'index.html',
                  page_template = 'index_page.html' ):

    try:
        if request.method == 'POST':        

            context = {}
            contextList = []
            keyWord = request.POST['keyWord']
            print keyWord   
            utilsOBJ = eScraperUtils()
            results = utilsOBJ.search('productCategory:%(keyWord)s or productSubCategory:%(keyWord)s or productDesc:%(keyWord)s' % {'keyWord' : keyWord})
            for i in results['hits']['hits']:
                contextDict = i['_source']
                contextDict['image_paths'] = json.loads(contextDict['image_paths'])   
                contextList.append(contextDict)            

            context.update({'contextList':contextList,'page_template': page_template})
            if request.is_ajax():    # override the template and use the 'page' style instead.
                template = page_template

        return HttpResponse(template, json.dumps(context), context_instance=RequestContext(request),
                                  content_type="application/json")    
    except :        
        return renderError('%s' % (traceback.format_exc()))

#------------------------------------------------------------------------------     

index.html :

<html>
<head>
    <title>Fashion</title>
    <link rel="stylesheet" type="text/css" href="static/css/style.css">
</head>
<body>

<form action="">
    {% csrf_token %}
    <input id="query" type="text" />
    <input id="search-submit" type="button" value="Search" />    
</form>

<div class="product_container">
    <ul class="product_list">
        <div class="endless_page_template">
            {% include page_template %}
        </div>
    </ul>
</div>


<div class="product_container">
    <ul class="product_list">
        <div class="endless_page_template">
            {% include page_template %}
        </div>
    </ul>
</div>


{% block js %}
<script src="http://code.jquery.com/jquery-latest.js"></script> 
<script src="static/js/endless_on_scroll.js"></script>
<script src="static/js/endless-pagination.js"></script>    
<script>
    $.endlessPaginate({paginateOnScroll: true,
    endless_on_scroll_margin : 10,
    paginateOnScrollChunkSize: 5
});</script>

<script type="text/javascript"> 
$("#search-submit").click(function() {  
    // Get the query string from the text field
    var query = $("#query").val();
    alert(query);    
    data = { 'csrfmiddlewaretoken': '{{ csrf_token }}', 'keyWord' : query};
    // Retrieve a page from the server and insert its contents
    // into the selected document.    
    $.ajax({
    type: "POST",
    url: '/search/',
    data: data,   
    success: function(context,status){
            alert("Data: " + context + "Status: " + status);
    },
    error: function( error ){
        alert( error );
      },
    contentType: "application/json; charset=utf-8",
    dataType: 'json',
    });
});
</script>
{% endblock %}
</body>
</html>

index_page.html :

{% load endless %}
{% paginate 10 contextList %}
{% for item in contextList %}
    <li >
        <a href="{{ item.productURL }}" ><img src="/images/{{ item.image_paths.0 }}/" height="100" width="100" border='1px solid'/></a>
        <br>
        <span class="price">
        <span class="mrp">MRP : {{ item.productMRP}}</span>
        {% if item.productPrice %}<br>
        <span class="discounted_price">Offer Price : {{ item.productPrice}}</span>
        {%endif%}
        </span>
    </li>  
{% endfor %}

{% show_more "even more" "working" %}

What i want is to fetch the server response and update the contextList .... But it is not working....

도움이 되었습니까?

해결책

The problem you're facing is that you're trying to update a Django template compiled variable called context_list this won't happen magically by using AJAX since Django has precompiled the HTML you're serving when you hit the page initially.

You can't circumvent this but you can work around it and below I'll show you two ways of doing it.

Your success() handler in your jQuery script that you have that manages the search gets the newly HTML that you've recompiled but you're not using it anywhere ergo, it won't work. In this case you're just logging some stuff out to console. (This would be where you're using option #2.)

You have two options as I see it. (It's a lot of code so I'll give you the pointers and not the implementation, won't strip you of all the fun!)

I'll give you a quick run down of both and then you can decide which way you want to take.

  1. You can use jQuerys $.load() method in order to fetch a recompiled template.
  2. You can use $.getJSON() and get the objects in JSON format and then update the HTML accordingly.

First option - $.load()

#Django
def search_view(keyword, request):
   search_result = SearchModel.objects.filter(some_field=keyword)
   t = loader.get_template("some_result_template.html")                
   c = Context({'search_results':search_result})
   return render(t.render(c))

#jQuery
$("#result").load("url_to_your_search", { 'keyword': 'search_me' } );

Second option - $.getJSON()

#Django
from django.core import serializers

def search_view(keyword, request):
    search_result = SearchModel.objects.filter(some_field=keyword)
    json_data = serializers.serialize('json', search_result)
    return HttpResponse(json_data, mimetype='application/json')

#jQuery
$.getJSON('url_to_your_search_view', { keyword: "search_me" }, function(json_data) {
  var items = [];

  $.each(json_data, function(key, val) {
    items.push('<li id="' + key + '">' + val + '</li>');
  });

  $('<ul/>', {
    'class': 'my-new-list',
    html: items.join('')
  }).appendTo('body');
});

Now the JSON code is taken straight from the docs, so you would have to modify it but you get the gist of what's needed in order for yours to work.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top