1

I was asked this on an interview presumably to see if I understood the separation between the Template layer and the Model layer.

My understanding is that template variables are essentially:

  1. A static copy of the instance (such that all the properties can be accessed)
  2. An instance that has all of the method with arguments "hidden" (such that they can't be called, but methods without arguments can be called )

Therefore, if you had a model with only methods with no arguments and passed an instance into a template could you say that it was a static copy of the instance? Is this even a correct way to think about template variables?

UPDATE:

Is the template (view) layer able to update models (e.g. from a custom context processor)? If no, then how is this prevented by the Django framework if it's not making copies of the model instance? If yes, then wouldn't this be a major deviation from typical web framework MVC design where data only flows in one direction from Model to View?

Charlie
  • 2,004
  • 6
  • 20
  • 40
  • it makes no sense to ask whether "Django variables" are "model instances". If you pass a model instance to a Django template, then yes the variable is a model instance; but you can also pass a string, int, other class instance, or anything you like, and the template variable will be of that type. – Daniel Roseman Sep 10 '15 at 18:45
  • And no, it's absolutely incorrect to think of these as static no-method copies. – Daniel Roseman Sep 10 '15 at 18:46

3 Answers3

2

The issue isn't that the variables are static copies. It's just that the template language itself doesn't allow you to call methods which take arguments. It's still the same object under the hood you're accessing, you just have no way to express certain programmatic concepts (assignment, passing arguments, etc.) in the language.

To answer your update: Yes the template layer could update models if the model had a method which modified the object and that method didn't take any arguments. But just because you can do a thing doesn't mean you should do a thing. Don't assume that because the developers of Django haven't absolutely prevented something means it's totally acceptable, but if that's what you really want to do, there's nothing to stop you.

Chad S.
  • 6,252
  • 15
  • 25
1

The template within Django is actually python code that translates parsed lines within the html file into python code, and injects their results directly in to the generated html file. Ergo, all objects and variables passed to a template are being passed to this python code (or function/module) that does all the work.

When you call:

render(request, 'template.html', {'data': [1,2,3...],})

you're actually calling a python function that takes the file template.html as an argument, parses it, calculates whatever lines are within the {{ }} and {% %} blocks, and replaces them with results. The number of operations that can be evaluated are limited, since the python code (or, template engine) does not evaluate those functions.

So, to answer your doubt, the instance variables that are passed to a template are actually being passed to the python template engine that handles all the work, and calls the methods to be called. It acts like a subset of python in respect to what operations are supported and which methods are callable.

Remember that template filters allow you to call methods with arguments over instance variables passed to the template, with the template filter being explicitly loaded in to the template engine. This works just like an import where the template engine knows the method, it's arguments, and results.

coolharsh55
  • 1,179
  • 4
  • 12
  • 27
  • So your answer to the question is yes? Also do you agree that they are static copies or is that not enforced? It seems like a bad design if a template engine could inadvertently change model data and would in fact no longer be MVC. – Charlie Sep 10 '15 at 19:08
  • How can you *possibly* get "yes" from this answer? There is no copying going on. – Daniel Roseman Sep 10 '15 at 19:44
  • As @DanielRoseman said, your view that the object is a `static`, or an immutable copy of the object is incorrect. The object reference is passed like any other object references in python. Django is not a "MVC" in the traditional sense. If you want to think of it in that sense, – coolharsh55 Sep 12 '15 at 07:34
0

For future readers the core of my issue was related to pass by reference confusion. I forgot about how Python handles an object passed into a function. Basically, it does not let you modify the reference object from the outer scope see here and here. Therefore it would be hard for data to accidentally flow back to the model (as can easily happen in desktop MVC implementations).

I'm surprised no one thought to point this out as it's a common misunderstanding with Python so I wanted to capture it here.

Community
  • 1
  • 1
Charlie
  • 2,004
  • 6
  • 20
  • 40