2

I'm having a difficult time passing variables from the python backend to javascript. A lot of my variables look like this in javascript:

if ('{{ user.has_paid_plan}}' == 'True') {
    isPayingUser = true;
} else {
    isPayingUser = false;
}

It's ugly and I'm sure there's a much cleaner way to do this. How should this be done?

David542
  • 104,438
  • 178
  • 489
  • 842
  • on start of your js script first put all django variables in js variables. eg - `var has_paid_plan = {{ user.has_paid_plan }}`. Then use that js variable everywhere in rest of your js. This way you can also use these variables in external js files too. Other option is to use data attribute. You can have a data-has_plan in some div or anything. Then you can get its value using js/jQuery. I go with first option when I wil have only one user on a page, if I am showing a list of users, I will go with data attributes – Vaibhav Vishal Oct 19 '18 at 06:25
  • @VaibhavVishal if I just do `{{ user.has_paid_plan }}`, I get an error in javascript, because it is literally passed as `True` (string, no quotes). – David542 Oct 19 '18 at 06:27
  • you can json serialize it in views. It will get converted to `true`, or use quotes and check for `"True"` or `"False"` – Vaibhav Vishal Oct 19 '18 at 06:28
  • @VaibhavVishal no, I also use the django variables as well. This is a template that has both html/django templating as well as javascript. – David542 Oct 19 '18 at 06:29
  • @David542 Change it to `var foo = "{{ foo }}";` then. – Selcuk Oct 19 '18 at 06:29
  • not related to your question, but in my personal opinion don't use django templates. Use django_rest_framework on backend and react or something like that on frontend. React can use your rest api. Also this way its easier to create mobile apps later as no changes in backend code will be required. It minimizes the backend code a lot. I remember going down from ~500 lines to ~50 in one of my views.py after switching to rest_api – Vaibhav Vishal Oct 19 '18 at 06:38

4 Answers4

2

This may be an odd approach, but I suppose one way to solve this would be to pass a json object as a variable, which would contain all other variables. For example:

def user(request):
    user = request.user

    ctx = {
      'isPayingUser': user.is_paying_user()
      'age': user.age
      'username': user.email
    }

    json_ctx = json.dumps(ctx)
    ctx['json_ctx'] = json_ctx

    return render(request, 'template.html', ctx)

In this way you have access to all the django/python variables, and you also have all the variables properly json-encoded as the "json_ctx" object which you can use in your javascript.

David542
  • 104,438
  • 178
  • 489
  • 842
  • 1
    It would be nice if you add an example of how to use the json variable in javascript – yuv Jun 08 '21 at 12:23
2

Let's keep things simple. You don't have to use any other response type like JSON or anything else. The first thing that you do is pass the value from the backend. Assuming User model has a field as "has_paid_plan" as a BooleanField. If not please convert the same to a BooleanField.

views.py

context = dict()
context['user'] = user_instance
return render(request, 'template.html', context)

template.html

Add this to your script.

<script>
   .... // other code
    {% if user.has_paid_plan %}
        isPayingUser = true;
    {% else %}
        isPayingUser = false;
    {% endif %}
</script>

Try to keep things simple. It's a good practice. Hope this helps.

Ankit Singh
  • 263
  • 1
  • 3
  • 12
1
<input type='hidden' value='{{ user.has_paid_plan}}' id='has_paid_plan' />


if ($('#has_paid_plan').val() == 'True') {
    isPayingUser = true;
} else {
    isPayingUser = false;
}
David542
  • 104,438
  • 178
  • 489
  • 842
daniel
  • 11
  • 2
  • this way is even uglier than I have it currently (which I thought was as bad as it could get). Note that what I'm currently doing works -- I just want to see if there's a suggested practice for how to do it better. – David542 Oct 19 '18 at 06:30
  • I understand the deviation, I rarely use the template function that comes with django, the front end usually uses vue, or uses asynchronous loading (the backend is packaged into json, and parsing with javascript is particularly simple) – daniel Oct 19 '18 at 06:42
  • While this might answer the authors question, it lacks some explaining words and links to documentation. Raw code snippets are not very helpful without some phrases around it. You may also find [how to write a good answer](https://stackoverflow.com/help/how-to-answer) very helpful. Please edit your answer. – hellow Oct 19 '18 at 09:21
-1

another solution:

<script>
const isAuthenticated = ${str(user.is_authenticated).lower()}
</script>
Duc Trung Mai
  • 2,141
  • 1
  • 24
  • 23