【问题标题】:Converting Boolean value from Javascript to Django?将布尔值从 Javascript 转换为 Django?
【发布时间】:2013-08-13 06:24:44
【问题描述】:

我注意到当布尔数据从 javascript 发送到 Django 视图时,它作为“true”/“false”(小写)而不是“True”/“False”(大写)传递。这会导致我的应用程序出现意外行为。例如:

vote.js

    ....
    var xhr = {
        'isUpvote': isUpvote
    };

    $.post(location.href, xhr, function(data) {
        doSomething()
    });

    return false;
});

views.py

def post(self, request, *args, **kwargs):
    isUpvote = request.POST.get('isUpvote')
    vote, created = Vote.objects.get_or_create(user_voted=user_voted)

    vote.isUp = isUpvote
    vote.save()

当我保存这个投票并检查我的 Django 管理页面时,“isUpvote”总是设置为 True,无论是从 javascript 传递的是 true 还是 false。那么将javascript的“真/假”布尔值转换为Django的“真/假”值的最佳方法是什么?

谢谢!!

添加:::::

好吧,我添加了一些“打印”行来检查我是否做错了什么:

    print(vote.isUp)
    vote.isUp = isUpvote
    print(vote.isUp)

    vote.save()

结果:

    True
    false    //lowercase

然后当我检查我的 Django 管理员时,它被保存为“True”!!! 所以我猜这意味着由于某种奇怪的原因将小写字母“false”保存为 Django“True”值....

【问题讨论】:

  • 您确定您的请求正确吗?检查下面的答案
  • url编码的表单数据中只有字符串,可以使用json传输布尔数据。或者您可以检查isUpvote 是否为字符串"true"(或"false")并设置适当的值。
  • @user2492270,如果 isUpvote 保存为字符串(而不是布尔值),那么我认为 Python 会将其视为“非空”(因此为真),即使该字符串是“假”。

标签: javascript jquery python ajax django


【解决方案1】:

将 'isUpvote' 值作为字符串 'true' 或 'false' 并使用 json 来区分其布尔值可能会更好

import json

isUpvote = json.loads(request.POST.get('isUpvote', 'false')) # python boolean

【讨论】:

    【解决方案2】:

    试试这个。

    from django.utils import simplejson
    
    def post(self, request, *args, **kwargs):
        isUpvote = simplejson.loads(request.POST.get('isUpvote'))
    

    【讨论】:

    • 在 Django 1.5 及更高版本中,您应该改用本机 Python 模块 json,请参阅下面的答案。
    【解决方案3】:

    我遇到了同样的问题,我用更清晰的方式解决了问题。

    问题:

    如果我将以下 JSON 发送到服务器,布尔字段以 test("true", "false") 的形式出现,我必须以 request.POST.getlist("catalogues[]") 的形式访问 catalogues。我也不能轻易进行表单验证。

    var data = {
       "name": "foo",
       "catalogues": [1,2,3],
       "is_active": false
    }
    
    $.post(url, data, doSomething);
    

    Django 请求处理程序:

    def post(self, request, **kwargs):
        catalogues = request.POST.getlist('catalogues[]')  # this is not so good
        is_active = json.loads(request.POST.get('is_active')) # this is not too
    

    解决方案

    我通过将 json 数据作为 string 发送并在服务器端将数据转换回 json 来解决这个问题。

    var reqData = JSON.stringify({"data": data}) // Converting to string
    $.post(url, reqData, doSomething);
    

    Django 请求处理程序:

    def post(self, request, **kwargs):
        data = json.loads(request.POST.get('data'))  # Load from string
    
        catalogues = data['catalogues'] 
        is_active = data['is_active']
    

    现在我可以进行表单验证并且代码更简洁了:)

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题(Javascript 的真/假 - Python 需要真/假),但使用一个小函数修复了它:

      def convert_trueTrue_falseFalse(input):
          if input.lower() == 'false':
              return False
          elif input.lower() == 'true':
              return True
          else:
              raise ValueError("...")
      

      它可能对某人有用。

      【讨论】:

        【解决方案5】:

        Javascript 转换为布尔值的方式是

        //你的变量就是你要转换的那个
        var myBool = Boolean(yourVariable);
        

        但是在您上面的代码中,您似乎在这里传递了一个字符串而不是变量

        isUpvote = request.POST.get('isUpvote')

        你确定你做对了吗?

        【讨论】:

        • 感谢您的回复!!我在我的问题中添加了一些额外的信息 :( 仍然没有弄清楚出了什么问题
        • @user2492270 检查这两行 isUpvote = request.POST.get('isUpvote') 和 vote, created = Vote.objects.get_or_create(user_voted=user_voted) 。我认为您在发送请求时将 isUpvote 视为字符串。我不确定这是否是它在 django 中完成的方式。还要记住,您在请求中发送了一个对象xhr。尝试在线查看如何访问对象属性。我能做的就这么多......如果有帮助,请随时接受答案。
        【解决方案6】:

        由于 Django 1.5 放弃了对 Python 2.5 的支持,django.utils.simplejson 不再是 Django 的一部分,因为您可以改用 Python 的内置 json,它具有相同的 API:

        import json
        
        def view_function(request):
            json_boolean_to_python_boolean = json.loads(request.POST.get('json_field'))
        

        【讨论】:

          【解决方案7】:

          我在从js调用django rest api时遇到了同样的问题,这样解决了:

          isUpvote = request.POST.get("isUpvote")
          isUpvote = isUpvote == True or isUpvote == "true" or isUpvote == "True"
          

          【讨论】:

          • 我建议您添加文字以解释为什么这是解决方案。如果我理解正确,这可能是对问题的一个很好的答案,但没有附带解释,以及为什么它比已经发布的其他答案更好,它可能会被删除。
          【解决方案8】:

          另一种选择是使用 ast(Abstract Syntax Tree) 库中的 literal_eval()。

          在 Javascript/jquery 中:

          $.ajax({
              url: <!-- url for your view -->,
              type: "POST",
              data: {
                  is_enabled: $("#id_enable_feature").prop("checked").toString() <!-- Here it's either true or false> 
              }
          })
          

          在您的 Django 视图中,

          from ast import literal_eval
          
          def example_view(request):
              is_enabled = literal_eval((request.POST.get('is_enabled')).capitalize())
              print(is_enabled)    # Here, you can check the boolean value in python like True or False
          

          【讨论】:

            【解决方案9】:

            用 Python 的ternary operator:

            isUpvote = True if request.POST.get("isUpvote") == "true" else False
            

            另外我应该提到,如果您正在使用 Django 的表单并尝试通过 Ajax 将兼容的布尔值传递给 Form 或 ModelForm 类,则需要使用 Django 期望的精确值。

            假设您的模型上有null=True:

            1. 未知
            2. 是(正确)
            3. 否(错误)

            因此,例如,以下将正确地将布尔数据传递到 Django 的表单:

            <input type="radio" id="radio1" name="response" value="2">
            <label for="radio1">Yes</label>
            <input type="radio" id="radio2" name="response" value="3">
            <label for="radio2">No</label>
            

            【讨论】:

            • 这不是一个糟糕的答案,但它使用ternary operator,而不是列表理解。
            【解决方案10】:

            我通常将 JavaScript 布尔值转换为数字。

            var xhr = {
                'isUpvote': Number(isUpvote)
            };
            

            在python中:

            try:
              is_upvote = bool(int(request.POST.get('isUpvote', 0)))
            except ValueError:
              // handle exception here
            

            【讨论】:

              【解决方案11】:

              您只能将字符串“true”或“false”传递给布尔值

              isUpvote = request.POST.get('isUpvote') == 'true'
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2016-04-27
                • 2012-02-25
                • 2015-02-20
                • 1970-01-01
                • 1970-01-01
                • 2017-07-02
                • 2021-06-27
                • 2017-03-07
                相关资源
                最近更新 更多