当前位置:  开发笔记 > 编程语言 > 正文

在Django中是否存在用于编写不引人注目的JavaScript和/或制作AJAX表单提交的惯用方法?

如何解决《在Django中是否存在用于编写不引人注目的JavaScript和/或制作AJAX表单提交的惯用方法?》经验,为你挑选了1个好方法。

我是一名Ruby/Rails开发人员,现在在Python/Django商店工作.我已经开始热衷于Python了,但是,我仍然在努力寻找与Rails在某些方面相当的Django.我当前和未来的许多工作都将专注于向我们的API发出AJAX请求.作为Rails开发人员,我使用了不引人注目的javascript,特别是在表单提交时添加了一个数据远程标记,如下所示.

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

我想我真的想说的是我假设Django会为Rails提供类似的"魔力",因为每次我想要发出一个AJAX请求时都不必编写jQuery AJAX函数.我写了一个粗略的比较(非常粗略),我将如何写出这两个.我想知道这对于我在Django中的Rails中做什么是不正确的.我知道StackOverflow并不适用于意见,但我认为无论你使用什么语言/框架,即不通过反复写出AJAX函数来干扰代码,违反原则的原则并不违背意见,它更像是打破了一个公认的规则.

我目前在Django中处理AJAX请求的方法感觉不对,或者我可能只是习惯了通过data-remote ="true"属性提供的"魔术"Rails.非常喜欢这个主题的一些指导,以帮助我确定一个可靠的方法,谢谢.

钢轨

视图/ some_controller/form.html.erb

FORM FIELDS HERE

资产/ Java脚本/ some_model.js

$('body').on('ajax:success', '#form', function(event, data) {
  DO SOME STUFF HERE
});

控制器/ some_controller.rb

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

some_app /模板/ form.html

FORM FIELDS HERE OR {{ BUILD_FORM_FROM_CONTEXT }}

some_app /静态/资产/ JS/some_app.js

$("#form").on("submit", function(event) {
  $.ajax({
    type: "POST",
    beforeSend: function (request) {
      request.setRequestHeader("X-CSRFToken", csrftoken);
    },
    data: data,
    url: "endpoint",
    dataType: 'json',
    contentType: 'application/json',
    }).done(function(data) {
      cb(null, data)
    }).fail(function(data) {
      cb(data)
    }).always(function(data) {
      cb(data)
    })
  });
});

Yuji 'Tomita.. 7

你的问题的答案是否定的.Django与AJAX没有惯用的方法.它对AJAX没有任何意见,尤其是在前端.

由于基于类的视图(CBV)的结构,后端倾向于遵循更多类似的模式; 通常会看到一个简单的AJAXResponseMixin混合到CBV中,它利用了所有通用视图通过单一方法可靠地生成其上下文的事实get_context_data.mixin可以只接受所述上下文并将其转换为JSON.

django没有强制使用AJAX模式; 你只需要按自己喜欢的方式建立自己的方式.

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

本练习的目的是向您展示这个想法中真正涉及的框架.这是一些代码行.

首先,让我们data-remote=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;
        })
    })
})

完成.现在让我们在模板中使用它:

{{ form.as_p }}

很酷,现在有些JS回应这个表单的提交:

$(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!");
    })
})

controller/django视图:

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()))

为了完成此示例,我们将修改初始jQuery脚本以基于新数据属性(例如data-partial-name)设置标头.

现在,我们的简单框架可以通过HTML数据属性在基于类的视图上调用特定方法.即设置data-partial="some-template-name.html"将触发YourView.handle_ajax_partial将返回呈现的HTML.

然后,您可以通过向函数添加默认处理程序来自动化所述调用的呈现/更新(data-remote如果data-partial已设置).



1> Yuji 'Tomita..:

你的问题的答案是否定的.Django与AJAX没有惯用的方法.它对AJAX没有任何意见,尤其是在前端.

由于基于类的视图(CBV)的结构,后端倾向于遵循更多类似的模式; 通常会看到一个简单的AJAXResponseMixin混合到CBV中,它利用了所有通用视图通过单一方法可靠地生成其上下文的事实get_context_data.mixin可以只接受所述上下文并将其转换为JSON.

django没有强制使用AJAX模式; 你只需要按自己喜欢的方式建立自己的方式.

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

本练习的目的是向您展示这个想法中真正涉及的框架.这是一些代码行.

首先,让我们data-remote=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;
        })
    })
})

完成.现在让我们在模板中使用它:

{{ form.as_p }}

很酷,现在有些JS回应这个表单的提交:

$(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!");
    })
})

controller/django视图:

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()))

为了完成此示例,我们将修改初始jQuery脚本以基于新数据属性(例如data-partial-name)设置标头.

现在,我们的简单框架可以通过HTML数据属性在基于类的视图上调用特定方法.即设置data-partial="some-template-name.html"将触发YourView.handle_ajax_partial将返回呈现的HTML.

然后,您可以通过向函数添加默认处理程序来自动化所述调用的呈现/更新(data-remote如果data-partial已设置).

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有