1

Hi I'm trying to display subjects names from my database using AJAX. That's my output right now:

[{"pk": 1, "model": "school.subjects", "fields": {"name": "Math 140"}},
{"pk": 2, "model": "school.subjects", "fields": {"name": "English 102"}},
{"pk": 3, "model": "school.subjects", "fields": {"name": "CS210"}}]

But I want to display only : How can I do that?

Math 140
English 102
CS210

Thats my view:

@csrf_exempt
def subjects_list(request):
    if request.is_ajax():
        user = request.user
        subjects = Subjects.objects.filter(user__exact = user)
        result = serializers.serialize("json", subjects, fields=('name'))
    else:
        result = "blablabl"
    return HttpResponse(result)

And thats my test.html

{% extends "base.html" %}
{% block main-menu %}
    <div id="result"></div>
    <script type="text/javascript">
        $(function() {
            $.get("/subjects-list", function(data){
                $("#result").append(data);
            });
        }); 
    </script>
{% endblock %}
Vor
  • 33,215
  • 43
  • 135
  • 193

2 Answers2

1

Don't serialize your models directly, it isn't safe as users would see sensible internal fields.

You want to use a real API engine, like django-tastypie or django-piston. With this kind of engine, you'll be able to select fields that you want to show, manage authorizations, output formats, etc...

For instance, with tastypie:

class SubjectResource(ModelResource):
    class Meta:
        queryset = Subject.objects.all()
        resource_name = 'subjects'
        fields = ['name']

Will produce:

{
  "objects": [
    {"name": "Math 140"},
    {"name": "English 102"},
    {"name": "CS210"},
  ]
}

Of course, you can delete the objects wrapper with the following instance method:

def alter_list_data_to_serialize(self, request, data):
    data[self.Meta.resource_name] = data['objects']
    del data['objects']
    del data['meta']
    return data

That's the cleanest way to go.

ldiqual
  • 15,015
  • 6
  • 52
  • 90
1

It is because the data you get back from the server is JSON. This needs to be parsed before it is loaded into your DOM. You could do something like this:

Copying, then adding to your test.html...

{% extends "base.html" %}
{% block main-menu %}
    <div id="result"></div>
    <script type="text/javascript">
        $(function() {
            $.get("/subjects-list", function(data){
                var $results = $("#result");
                for (var i = 0; i < data.length; i++) {
                    $results.append(data[i]["fields"]["name"] + "<br/>");
                }
            }, "json");
        }); 
    </script>
{% endblock %}

With that said though, you may want to look into using a javascript templating library. There are a LOT of them out there. The general idea is that the library can handle turning the AJAX responses into HTML.

There are some stackoverflow question answering the question of which to use here:

Recommended JavaScript HTML template library for JQuery?

What is the preferred template library for jQuery?

In order to find more about this, you'll want to search for "javascript templating".

Community
  • 1
  • 1
almostflan
  • 640
  • 4
  • 15
  • It works fine, but just want to ask why do I need this line: var $results = $("#results"); ??? – Vor Aug 12 '12 at 20:41
  • The idea is that every time you say $("...."), jquery will go search for the item. If you store it in a variable, it only needs to search once. – almostflan Aug 12 '12 at 20:45
  • ohhh, I see,so it basically increase the performance. Thank you. – Vor Aug 12 '12 at 20:51
  • Correct. I believe it's somewhere in JQuery's best practices but I can't find a link. It's convention to call JQuery selector variables $foo. – almostflan Aug 12 '12 at 20:52