【问题标题】:Easiest way to update model values using Django with an AJAX form使用带有 AJAX 表单的 Django 更新模型值的最简单方法
【发布时间】:2019-07-03 01:23:02
【问题描述】:

我有一个 django 模型,其中包含一些带有相关选项的字段:

class Product(models.Model):
    CONDITION_CHOICES = (
        ("GOOD", "Good"),
        ("BAD", "Bad"),
        ("UNKNOWN", "Unknown"),
    )

    name = models.CharField(max_length=200, blank=True, null=True)
    colour = models.CharField(max_length=200, blank=True, null=True)

    condition = models.CharField(max_length=20, choices=CONDITION_CHOICES, blank=True, null=True)
    condition_source = models.CharField(max_length=20, blank=True, null=True)
    condition_last_updated = models.DateTimeField(blank=True, null=True)

我还有一个引导驱动的表单,如下所示:

<div class="form-group">
    <label class="control-label"><strong>Condition</strong></label>
    <br/>
    <div class="btn-group btn-group-toggle" data-toggle="buttons">
        <label class="btn btn-outline-primary">
            <input type="radio" name="condition" value="GOOD" autocomplete="off">
            Good
        </label>
        <label class="btn btn-outline-primary">
            <input type="radio" name="condition" value="BAD" autocomplete="off">
            Bad
        </label>
        <label class="btn btn-outline-primary">
            <input type="radio" name="condition" value="UNKNOWN" autocomplete="off">
            Unknown
        </label>
    </div>
</div>

我试图做到这一点,以便当用户单击 UI 中的一个按钮时,更新 Product 模型(特别是 condition、condition_source 和 condition_last_updated 字段)。实际模型有多个与选择选项相关联的字段,因此我希望模型能够实时更新,而无需在用户处理表单时重新加载页面。

任何指导都将不胜感激 - 我查看了 intercooler.js,但不确定这是否是适合这项工作的工具。

【问题讨论】:

    标签: json ajax django twitter-bootstrap bootstrap-4


    【解决方案1】:

    由于您尚未指定 condition_source 应包含的内容,因此我已将其设置为字符串 some_source

    阿贾克斯:

    $('.btn').on('click', function(){
        $.post(
               '/your_vew/',
               {
                 'source': "some_source",
                 'condition': $(this).find('input').val(),
                 'csrfmiddlewaretoken': '{{csrf_token}}'
               },
               function(data){
                  console.log(data.response);
               }
         );    
    });  
    

    urls.py:

    urlpatterns = [
        ...
        path('your_vew/', views.your_view), 
        ...
    ]
    

    views.py:

    from django.http import JsonResponse
    from datetime import datetime
    
    def your_view(request):
        data = {'response': ''}
        if request.method == 'POST':
            p1 = Product.objects.filter(pk=1).update(
                  condition_source=request.POST.get('source'),
                  condition=request.POST.get('condition'),
                  condition_last_updated=datetime.now()
                )
            if p1:
                data['response'] = 'Record updated!'    
        return JsonResponse(data) 
    

    【讨论】:

      【解决方案2】:

      现在,您有几个选择。我所做的是我以类的形式使用了 Jquery ajax 方法,并在这个类中为我的应用程序设置了我的函数。 Django 需要 csrf 令牌才能处理传入请求。所以我发现这两个函数从客户端检索 cookie csrf 令牌。

          function getCookie(name) {
          var cookieValue = null;
          if (document.cookie && document.cookie !== '') {
              var cookies = document.cookie.split(';');
              for (var i = 0; i < cookies.length; i++) {
                  var cookie = jQuery.trim(cookies[i]);
                  // Does this cookie string begin with the name we want?
                  if (cookie.substring(0, name.length + 1) === (name + '=')) {
                      cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                      break;
                  }
              }
          }
          return cookieValue;
      }
      
      function csrfSafeMethod(method) {
      // these HTTP methods do not require CSRF protection
          return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
      }
      

      一旦 csrf 令牌存储在变量中,您需要将其传递给 ajax beforeSend 函数,例如:

      ajax_setup(enable_async){
          enable_async = true;
          $.ajaxSetup({
          async: enable_async,
          beforeSend: function(xhr, settings) {
              if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                  xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
              }
          }
          });
      }
      }
      

      完整的 ajax 请求类似于

      update_user_language(user_id, lang, callback){
          this.ajax_setup(true);
          $.ajax({
              url: this.url,
              type: "POST",
              data: {
                  'user_id':user_id,
                  'lang':lang,
              },
              dataType: 'json',
              success: function(data){
                  db_request_after();
                  if(callback !== undefined) callback(data);
              },
              error: function(){
                  db_request_error();
              },
          });
      }
      

      注意回调变量。这允许 ajax 调用一个函数,传递从 web 服务检索到的数据。

      发送请求后,您需要设置 view.py 以接受请求并处理 POST 变量。

      def sample_view(request):
         if request.method == "POST"
             user_id = request.POST.get('user_id')
             lang = request.POST.get('lang')
             #update the model value
             user = User.objects.get(pk=user_id)
             user.language = lang
             user.save()
             return JsonResponse({'message':'user updated'})
         else:
             return render(...)
      

      【讨论】:

        猜你喜欢
        • 2012-12-15
        • 2011-02-21
        • 2017-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-16
        • 2010-10-12
        相关资源
        最近更新 更多