Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Django中是否有一种惯用的方法来编写不引人注目的JavaScript和/或提交AJAX表单?_Javascript_Python_Ajax_Django - Fatal编程技术网

Django中是否有一种惯用的方法来编写不引人注目的JavaScript和/或提交AJAX表单?

Django中是否有一种惯用的方法来编写不引人注目的JavaScript和/或提交AJAX表单?,javascript,python,ajax,django,Javascript,Python,Ajax,Django,我是一名Ruby/Rails开发人员,现在在Python/Django商店工作。我已经开始对Python热身了,但是,我仍然在努力寻找Django在我认为重要的某些方面可以与Rails相媲美。我当前和未来的很多工作都将集中于对API发出AJAX请求。作为一名Rails开发人员,我会使用不引人注目的javascript,尤其是在表单提交中添加一个数据远程标记,如下所示 然后,我将在控制器中编写一个方法来处理请求,并将在位于/assets/JS目录的JS文件中使用事件委托编写一个JavaScript

我是一名Ruby/Rails开发人员,现在在Python/Django商店工作。我已经开始对Python热身了,但是,我仍然在努力寻找Django在我认为重要的某些方面可以与Rails相媲美。我当前和未来的很多工作都将集中于对API发出AJAX请求。作为一名Rails开发人员,我会使用不引人注目的javascript,尤其是在表单提交中添加一个数据远程标记,如下所示

然后,我将在控制器中编写一个方法来处理请求,并将在位于/assets/JS目录的JS文件中使用事件委托编写一个JavaScript/jQuery函数来处理客户端的响应。我假设来到Django,也会有类似的方法来实现这种功能

我想我真正想说的是,我假设Django会提供与Rails类似的“魔力”,即不必在每次我想要发出AJAX请求时都写出jQueryAjax函数。我写了一个粗略的比较(非常粗略)我将如何写出这两个。我希望了解这是否是一个不正确的方法,我将在Django的Rails中执行。我知道StackOverflow不是用来发表意见的,但我认为不管你使用什么语言/框架,打破适用的原则,即不反复编写AJAX函数而导致代码干涸,这并不是真正违背意见,更像是打破了一条公认的规则

我目前在Django中处理AJAX请求的方法感觉是错误的,或者我只是习惯了Rails通过data remote=“true”属性提供的“神奇”功能。希望您能给我一些关于这个话题的指导,帮助我确定一个可靠的方法,谢谢

导轨

views/some\u controller/form.html.erb

<form action="<%= endpoint %>" method="post" data-remote="true" id="form">
  FORM FIELDS HERE
</form>
def some_ajax_action
  if request.xhr?
    THIS IS AN AJAX REQUEST RENDER A VIEW PARTIAL & 
    MANIPULATE THE DOM WITH JS OR RESPOND WITH JSON
  else
    THIS ISNT AN AJAX REQUEST
  end
end
控制器/some_controller.rb

<form action="<%= endpoint %>" method="post" data-remote="true" id="form">
  FORM FIELDS HERE
</form>
def some_ajax_action
  if request.xhr?
    THIS IS AN AJAX REQUEST RENDER A VIEW PARTIAL & 
    MANIPULATE THE DOM WITH JS OR RESPOND WITH JSON
  else
    THIS ISNT AN AJAX REQUEST
  end
end
DJANGO

一些应用程序/模板/form.html

<form action="{% url 'app:view' %}" method="post" id="form">
   FORM FIELDS HERE OR {{ BUILD_FORM_FROM_CONTEXT }} 
</form>

这不是在Django中轻松实现的方法,但是通过几个额外的库,您可以更轻松地处理ajax表单帖子

CsrfProtection.js-这将把csrf令牌头附加到ajax请求中

(function() {
  var csrfSafeMethod, sameOrigin;

  csrfSafeMethod = function(method) {
    return /^(GET|HEAD|OPTIONS|TRACE)$/.test(method);
  };

  sameOrigin = function(url) {
    var host, origin, protocol, sr_origin;
    host = document.location.host;
    protocol = document.location.protocol;
    sr_origin = '#' + host;
    origin = protocol + sr_origin;
    return (url === origin || url.slice(0, origin.length + 1) === origin + '/') || (url === sr_origin || url.slice(0, sr_origin.length + 1) === sr_origin + '/') || !(/^(\/\/|http:|https:).*/.test(url));
  };

  $.ajaxSetup({
    beforeSend: function(xhr, settings) {
      if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
        return xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
      }
    }
  });

}).call(this);
然后包括javascript库。使用此库将允许您执行以下操作:

$('#form_id').ajaxSubmit({
    success: function(response) {console.log(response);},
    error: function(response) {console.log(response);}
});

它可能不像您在Ruby中列出的那样简单,但它确实减少了csrf令牌的重复和表单序列化。

我不相信django本身就有一个习惯用法。然而,也有可重用的应用程序,它们确实提供了非常常用的实现

例如,Crispy表单可以简化django ajax表单。在请求之前,无需进行任何csrf处理。他们的例子如下:


您的问题的答案是否定的。使用Django实现AJAX没有惯用的方法。它对AJAX没有意见,尤其是在前端

由于基于类的视图(CBV)的结构,后端倾向于遵循更相似的模式;常见的情况是,CBV中混合了一个简单的
AJAXResponseMixin
,它利用了所有通用视图通过单个方法可靠地生成上下文的事实
get\u context\u data
。mixin只需获取所述上下文并将其转换为JSON即可

django没有被迫使用AJAX模式;你只需要按照你喜欢的方式建造自己的房子

如果您喜欢rails示例的工作方式,为什么不呢

本练习的目的是向您展示这个想法中真正涉及的框架是多么少。这是几行代码

首先,让我们使用您概述的语法重现您的
dataremote=True
标记和事件侦听器系统。注意,这都是伪代码

$(function() {
    $("[data-remote=true]").each(function(index, el) {
        $(el).submit(function(ev) {
            ev.preventDefault(); // disable default form submit. We are using ajax.
            $.ajax({
                url: $(this).attr('action') || '',
                data: $(this).serialize(),
                method: $(this).attr('method') || 'get',
                success: function(response) {
                    // on success, trigger an event with the response data
                    $(el).trigger('ajax:success', [response]);
                },
                error: function(xhr) {
                    $(el).trigger('ajax:error', [xhr]);
                }
            })
            return false;
        })
    })
})
完成。现在让我们在模板中使用它: 控制器/django视图: 关于如何作为框架和可重用模式应用的想法,包括许多框架共有的部分呈现。 为了完成本例,我们将修改初始jQuery脚本,以基于新的数据属性(如数据部分名称)设置头

现在,我们的简单框架可以通过HTML数据属性在基于类的视图上调用特定方法。i、 e.设置
data partial=“some template name.html”
将触发
YourView.handle\u ajax\u partial
,它将返回呈现的html


如果设置了
data-partial
,则可以通过向
data-remote
函数添加默认处理程序来自动呈现/更新所述调用。

“有没有一种惯用的方法将Ruby/Rails惯用表达为惯用Python/Django?”这是一个完全可以接受的问题。这表明你已经做了研究。你看过这个了吗?嘿,杰森,我见过那些医生。这是处理调用是否为AJAX的好方法。但我想我的问题更多的是关于是否有一种类似于Rails使用UJS的惯用方法。我发现了一个Django UJS库,但它似乎没有得到维护。将
data remote=“true”
添加到HTML表单或链接会通过AJAX发送请求。我在想也许一个模板过滤器可以用来做同样的事情。我将做更多的研究并找出答案。AFAIK大多数Rails的“魔力”来自Rails提供的JavaScript插件(在您的示例中)。Django只关注Python,不提供太多的内置模板和现成的静态文件(除了在像admin这样的成熟解决方案中),因此您需要以简单的方式完成。但是,如果你想自己实现封装这些内容,没有什么可以阻挡你。@evkline:你能对提供的答案给出一些反馈吗?这有助于我奖励赏金。如果你已经用不同的方式解决了这个问题,你可以写下你的解决方案作为答案。
$(function() {
    $("[data-remote=true]").each(function(index, el) {
        $(el).submit(function(ev) {
            ev.preventDefault(); // disable default form submit. We are using ajax.
            $.ajax({
                url: $(this).attr('action') || '',
                data: $(this).serialize(),
                method: $(this).attr('method') || 'get',
                success: function(response) {
                    // on success, trigger an event with the response data
                    $(el).trigger('ajax:success', [response]);
                },
                error: function(xhr) {
                    $(el).trigger('ajax:error', [xhr]);
                }
            })
            return false;
        })
    })
})
<form id="my-django-form" method="POST" data-remote="true" action="some-controller">
    {{ form.as_p }}
    <input type="submit" />
</form>
$(function() {
    $('body').on('ajax:success', '#my-django-form', function(event, data) {
        alert("My barebones ajax framework was successful!", data);
    })
    $('body').on('error', '#my-django-form', function(event, data) {
        alert("Whoops, error!");
    })
})
def some_ajax_action(request):
    """ Some basic AJAX Handler.
    """
    if request.is_ajax():
        return http.HttpResponse(json.dumps({
            'this-is': 'some-json',
        }))
    else:
        print "This isn't an ajax request"
class AJAXFrameworkMixin(object):
    """ A more advanced, reusable pattern for class based views.
    Perhaps also allowing partial rendering via custom header `RENDER_PARTIAL` used by the jQuery request.
    """
    def dispatch(self, request, *args, **kwargs):
        if request.is_ajax():
            partial = request.META.get('X_RENDER_PARTIAL')
            if partial:
                return self.handle_ajax_partial(request, partial)
            return self.handle_ajax(request)

        return super(AJAXFrameworkMixin, self).dispatch(request, *args, **kwargs)

    def handle_ajax(self, request):
        """ Ajax specific handler.
        Convert this view context into JSON.
        """
        ctx = self.get_context_data()
        return http.HttpResponse(json.dumps(ctx))

    def handle_ajax_partial(self, request, partial):
        """ Given a render partial header from the barebones AJAX framework, render said partial with context.
        """
        t = template.loader.get_template(partial)
        return t.render(template.RequestContext(request, self.get_context_data()))