Philip007
Philip007

Reputation: 3230

Django: can view return render to ajax calls?

Say I have a view function which have many if/else branches for handling different request situations like whether it's POST/GET/form valid or not/etc. For every branch, I use render to return a http response object. All goes well.

My question is: is that efficient? For example, for Branch A in our view, I render context_A = {key1:value1, key2:value2,...key10:value10} with the template. Later the user request the same page, this time it ends up in Branch B in the view function, I call render again returning context_B with the same template. But context_B and context_A only have very slight difference, let's say only value10 changes while other key/value pairs are identical.

What's the best practice for such situation?Right now my solution is to call HttpResponse (rather than render) to return json data to jquery ajax method, provided that the whole template has been returned before. Then use JQuery methods to manipulate elements in DOM. But I fear it's not the best practice and will cause maintenance issues in the future. I figure that using context variables in all cases is a more Djangoish way. But how?


EDIT: code example

PS: I am new to web programming. Please bear with my code quality. Basically what I m doing is put context with default values , and return render() at the end of the view to guarantee at least a http response is returned. Then for every branch of if/else statement, I return json type of data (an image url) to jquery ajax method, and use jquery to put the url in src.

PS2:
Firstly, to avoid the page refresh, I have to use ajax to send the request (xhr), right? When I make a ajax request, do I have to return data to that ajax function or can I return data normally? For example, use render() in Django view?

I am trying hard to define my question better. Sorry for the trouble. Maybe someone could edit my question later to give better reference to future questioner.


def upload(request, size, slug):
    comp = get_object_or_404(ActiveComp, slug=slug)
    form= UploadForm()
    # default context
    context = {'comp':comp, 'form':form}

    if request.method == 'POST':
        temp_file = request.FILES.get('image', False)

        """
        3 validations
        """
        if ...:
            return HttpResponse(json.dumps({"src":"none"}), mimetype="application/json")

        # type checking (not REAL type checking, only file extension checking)
        if ... : 
            return HttpResponse(json.dumps({"src":"not-image"}), mimetype="application/json")

        # size checking
        if ... :
            return HttpResponse(json.dumps({"src":"too-big"}), mimetype="application/json")

        # put uploaded image in db
        # ...

        # store image name in session
        request.session['f1'] = img.name

        #get thumbnail url using sorl-thumbnail
        try:
            timg = get_thumbnail(img.image, "160x110", quality=80, crop="center")
        except:
            context['turl'] = 'error'
        else:
            return HttpResponse(json.dumps({"src":timg.url}), mimetype="application/json")  

    else: # GET
        try:
            img = Image.objects.filter(user=request.user)[0]
        except Exception:
            context['turl'] = "" 
        else:           
            timg = get_thumbnail(img.image, "160x110", quality=50)
            # store image name in session, so delete view can know the filename
            request.session['f1'] = img.name
            context['turl'] = timg.url

    return render(request, 'template_A.html', context)

Upvotes: 1

Views: 1158

Answers (2)

Matt Seymour
Matt Seymour

Reputation: 9395

@Philip007, when it comes to programming I respect that people have there own coding styles, thought processes and general ways of doing things.

If I was to inherit this code from you, yes I would make some changes to make the code a little more concise but I understand what your doing and the reasons behind it. For this reason i would say it was perfectly adequate code for the purpose.

I personally like to split out my GET and POST request into separate methods, only because I like a function to do only one thing (but this is my preference). I would probably also set a value in each of the if statements within the POST and have one return at the end of that code block; but again this is just general house keeping.

Upvotes: 0

Matt Seymour
Matt Seymour

Reputation: 9395

Pre-question edit

Efficient wise?

Depends on what you mean by efficient.

Are you talking about efficiency of the developer or efficiency of the code.

Personally, i try to keep the views as lightweight as possible; with as little logic in them as possible. This means I might have 2 or 3 templates for a given page. I would rather have multiple templates rather than one large monolithic template. It means I can visualize what the code is doing easier.

The thing to remember is developer time is expensive (possibly hundreds of dollar / pounds a day), and hardware is cheap. It is far more cost effective to be an efficient developer rather than trying to right highly efficient code.

So the long and short of it is you right what you believe makes you the most efficient developer and if you find it is slow then look for the performance gains or just throw hardware at it. This is becoming more and more the case with cloud computing being cheap.

Upvotes: 1

Related Questions