结合使用AngularJS和Django

时间:2022-09-01 20:13:14

原地址

好吧,我承认自己很懒,时间又不够用。

翻译的几个文章都是虎头蛇尾,但我保证这次肯定不太监。

关键的单词不翻译,实在觉得翻译成汉语很别扭,括号里是参考翻译。

有问题和建议尽管提出来,我会改进完善。

Tutorial: Using AngularJS with Django

原文:http://glynjackson.org/weblog/entry/django-angular.html      点我进原文

Posted on: 31 Jan 2014, 4:58 p.m. Categories: Django Frameworks Python

我原本打算写一个如何结合Angular和Django的快速入门,但最后证明这只是一篇喝了红牛后的冲动产物。抱歉草草结束。(这是作者原话)

看了几个结合使用Angular和Django的文章,我发现自己在重新发明*。尽管我给出的例子很粗糙,但是它们已经足够展示我在项目中如何操作。

Models (模型)

一个标准Django模型

/jobs/models.py

class Job(models.Model):

    name = models.CharField(max_length=50)

    description = models.TextField(null=True, blank=True)

目前为止还没什么特别之处。你所做的只是创建了一个简单的模型来存基本的工作信息。

The REST API (Tastypie)

AngularJS被发明来终结webservices,所以你只需要提供你刚创建的Job模型就足够了。

Django在创建 RESTful APIs 上很有一套。 TastyPie是为Django创建的极好的web服务框架。 TastyPie及其强大,易于配置和使用。 抛开个人喜好,使用Django REST framework也能做同样的事情,甚至能直接用Django构造你自己的API响应。 使用哪个的选择权在你。 这篇文章我会使用 TastyPie。

若你不熟悉TastyPie ,看这个文档(点我) 。我不会详说安装等细枝末节的东西。我假定你已经安装配置好了TastyPie ,并却已经准备好和我继续下去了。

首先,你需要为你的jobs创建一个resource。 TastyPie遵循“Resources”这样的理念, 它把resource作为end user和objects(这里指的是Job模型)的中介。

为Job模型创建一个适当的resource:

结合使用AngularJS和Django
class JobResource(ModelResource):
"""
API Facet
"""
class Meta:
queryset = Jobs.objects.all()
resource_name = 'job'
allowed_methods = ['post', 'get', 'patch', 'delete']
authentication = Authentication()
authorization = Authorization()
always_return_data = True
结合使用AngularJS和Django
我记得TastyPies官方文档建议在你的应用中用api.py来命名此文件。这也是我的做法,尽管它不是强制的。你可以随意命名,但是按照约定命名文件可以保证一致性。

JobResource 的一些设置已经超出了本文章的范围。但我乐于解释JobResource是继承自ModelResource的。 结合Tastypie与Django ORM两者使用。扩展它意味着你已经能够能深入API的基本实现了。

TastyPie 也能处理非ORM数据。通过直接扩展Resource,你也能够得到TastyPie提供的所有好处。 No SQL数据库描述如下(点我)。

现在你已经创建了模型和与之交互的方式。接下来,你需要一个把resource连接到实际URL的步骤,如此,AngularJS才能发挥它的作用。 简单的举例说明如何在Django URLConf里建立这样的连接。:

结合使用AngularJS和Django
from tastypie.api import Api
from .apps.your_app.api import JobResource v1_api = Api(api_name='v1')
v1_api.register(JobResource()) urlpatterns = patterns('', (r'^api/', include(v1_api.urls)),
)
结合使用AngularJS和Django
在JobResource指定resource_name属性是最后一步。现在,你已经创立了一个有效绑定Resource到Job模型上的API。 检查它在server上是否工作良好,用你的浏览器访问 http://127.0.0.1:8000/api/job/?format=json

Forms

在你深入AngularJS前,我们来创建一个Job form。 Job form会让你在你的应用中轻松编写Jobs。我知道你会问,为什么要这么做。

好吧,Django其中一个哲学就是,不做重复劳动(Don't repeat yourself (DRY))。 所以创建为AngularJS写HTML,然后在Django也这么做就显得极不合理,因为Django会帮你做这件事。你可能已经有了很多需要转换的forms。为什么要重复这个过程? 点击 django-angular. 这是一个很酷的包,你会喜欢它的。

Quote: "Django-Angular is a collection of utilities, which aim to ease the integration of Django with AngularJS by providing reusable components."

现在我架设你已经安装好了 Django-Angular 。把这些放进一个如'crispy forms'的包里,你会得到一个一站式的解决方案 -- 这是我为什么喜欢Django和它的社区。

结合使用AngularJS和Django
from .app.your_app.models import Job
from .apps.djangular.forms import NgFormValidationMixin, NgModelFormMixin, AddPlaceholderFormMixin class JobForm(NgModelFormMixin, forms.ModelForm):
"""
Job Form with a little crispy forms added!
"""
def __init__(self, *args, **kwargs):
super(JobForm, self).__init__(*args, **kwargs)
setup_bootstrap_helpers(self) class Meta:
model = Job
fields = ('name', 'description',) def setup_bootstrap_helpers(object):
object.helper = FormHelper()
object.helper.form_class = 'form-horizontal'
object.helper.label_class = 'col-lg-3'
object.helper.field_class = 'col-lg-8'
结合使用AngularJS和Django

On to AngularJS

为了简便,你需要创建如下三个模板。

templates
jobs/index.html
jobs/new.html
base.html

这说明你有一个叫job的app并且已经安装了。你的base模板会像下面一样:

/jobs/base.html

结合使用AngularJS和Django
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.2/css/bootstrap.min.css" rel="stylesheet"> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.js"></script>
<script src="/angular-ui-router.min.js"></script>
<script type="text/javascript" src="http://cdn.jsdelivr.net/restangular/latest/restangular.js"></script> </head>
<body>
{% block content %}{% endblock content %}
{% block extra_javascript %}{% endblock extra_javascript %}
</body>
</html>
结合使用AngularJS和Django

Django-Angular已经提供了很多很好的模板标签,这些标签包含了必要的javascript。我建议使用分布式目录网络(CDN)来加载必要的文件。如此做,你会得到明显的地理上的和宽带资源上的好处。

你需要创建一个page模板。index.html会作为主页,它会接收请求。

/jobs/index.html

结合使用AngularJS和Django
{% extends "base.html" %}
{% load i18n %}
{% block content %}
<div class="container content" ng-app="JobApp">
<div ui-view >Loading...</div>
</div>
{% endblock content %}
{% block extra_javascript %}
<script src="{{ STATIC_URL }}/javascript/app.js"></script>
{% endblock extra_javascript %}
结合使用AngularJS和Django

/javascript/app.js

结合使用AngularJS和Django
var app = angular.module('JobApp', [
'ui.router',
'restangular'
]) app.config(function ($stateProvider, $urlRouterProvider, RestangularProvider) {
// For any unmatched url, send to /route1
$urlRouterProvider.otherwise("/");
$stateProvider
.state('index', { url: "/",
templateUrl: "/static/html/partials/_job_list.html",
controller: "JobList"
}) .state('new', { url: "/new",
templateUrl: "/jobs/job-form",
controller: "JobFormCtrl"
})
}) app.controller("JobFormCtrl", ['$scope', 'Restangular', 'CbgenRestangular', '$q',
function ($scope, Restangular, CbgenRestangular, $q) { }])// end controller
结合使用AngularJS和Django

模板和js非常简单,它们继承自base模板。有几个必须要明白的属性你可能没见过。

第一个是 ng-app='JobApp'。 没有这个标签,AngularJS不会起作用。这个指令告诉AngularJS哪一个元素是应用的根元素。你所向根元素写入的东西会成为被AngularJS管理的一部分。

接下来,看你在index.html里引入的的脚本文件。 app.js 脚本定义了angular模块。 当应用被booted(启动)时, 一个angular模块就是函数的集合。

var app = angular.module('JobApp', [

上一行创建了名为JobApp的模块。 在index.html里你已经通过声明属性为ng-app='JobApp'来实例化它了。你所做的就是告诉AngularJS你想让app.js包含所需的所有。

实际上,你可以把ng-app设置成任何DOM中的元素。例如,如果你只想模板其中一个部分被AngularJS控制,你可以这样做:

<h2>I am not inside an AngularJS app</h2>
<div ng-app="embeddedApp">
<h3>Inside an AngularJS app</h3>
</div>

在app.js里的app.config展示了你URL路由(routing)。AngularJS通过默认的变量 $route 来提供URL路由,但是不太适当,并且有限制。

其中你已经包括进来的模板是 AngularUI Router ‘ui.router’。 AngularUI Router是另一个为AngularJS扩展的围绕状态扩展的路由框架。

你提供了仅仅一个叫做new的state,其实可以为你的应用包含许多不同的state。 甚至当没有state返回时,你可以添加一个默认的行为。

结合使用AngularJS和Django
$urlRouterProvider.otherwise("/");
$stateProvider
.state('index', { url: "/",
templateUrl: "static/html/somepage.html",
controller: "SomeController"
})
结合使用AngularJS和Django

如果你还不熟悉这些,看完此文我建议你读 AngularUI Router

最后你要了解的元素是ui-view。 这也是AngularUI Router 模型的一部分。 ui-view 指令告诉 $state 哪里放置你的模板,例如, templateUrl: "/job/new/"。

最后你要创建的模板是 /jobs/new.html。 这里包括了你刚才用 Django-Angular 创建的basic form。

{% load crispy_forms_tags %}
{% crispy JobForm %}
<button type="button" class="btn btn-default" ng-click="submitJob()">Create</button>

现在把view和URL连接到form。

/jobs/views.py

结合使用AngularJS和Django
from .forms import JobForm

class JobFormView(TemplateView):
template_name = "jobs/new.html" def get_context_data(self, **kwargs):
context = super(JobFormView, self).get_context_data(**kwargs)
context.update(JobForm=JobForm())
return context
结合使用AngularJS和Django

/jobs/urls.py

结合使用AngularJS和Django
from django.conf.urls import url
from django.conf.urls import patterns from .views import JobFormView urlpatterns = patterns('', url(r'^job-form/$',
login_required(JobFormView.as_view()),
name='job_form'), )
结合使用AngularJS和Django

用你的浏览器访问 http://127.0.0.1:8000/job/#new。 你会看到刚才的劳动成果。

Restangular is an AngularJS service that simplifies common GET, DELETE, and UPDATE requests with a minimum of client code. It's a perfect fit for any WebApp that consumes data from a RESTful API.  restangular

结合使用AngularJS和Django
app.controller("JobFormCtrl", ['$scope', 'Restangular', 'CbgenRestangular', '$q',
function ($scope, Restangular, CbgenRestangular, $q) { $scope.submitJob = function () {
var post_update_data = create_resource($scope, CbgenRestangular);
$q.when(post_update_data.then(
function (object) {
// success!
}, function (object){
// error!
console.log(object.data)
} ))
} }])// end controller app.factory('CbgenRestangular', function (Restangular) {
return Restangular.withConfig(function (RestangularConfigurer) {
RestangularConfigurer.setBaseUrl('/api/v1');
});
}) populate_scope_values = function ($scope) {
return {name: $scope.name, description: $scope.description };
}, create_resource = function ($scope, CbgenRestangular) {
var post_data = populate_scope_values($scope)
return CbgenRestangular.all('job').post(post_data)
},
结合使用AngularJS和Django

Where to go from here

Too much to cover in just one blog post. Best practices should be your next step and head over to egghead, best tutorials on the web in my opinion.

结合使用AngularJS和Django的更多相关文章

  1. Tutorial&colon; 结合使用AngularJS和Django

    好吧,我承认自己很懒,时间又不够用. 翻译的几个文章都是虎头蛇尾,但我保证这次肯定不太监. 关键的单词不翻译,实在觉得翻译成汉语很别扭,括号里是参考翻译. 有问题和建议尽管提出来,我会改进完善. Tu ...

  2. 解决AngularJS和Django模板标签冲突问题

    原地址 Django和AngularJS在模板中使用同样的符号来引用变量,例如 {{variable_name}}. 有两种解决办法,各有利弊.一个修改AngularJS模板语法,另一个使用Djang ...

  3. angularjs 与django标签语法冲突的解决办法

    在需要使用angularjs标签的地方套上verbatim标签,如: {% verbatim %} ... {% endverbatim %}

  4. Django 优秀资源大全

    版权: https://github.com/haiiiiiyun/awesome-django-cn 转自:https://www.jianshu.com/p/38c4dd6d8e28 Awesom ...

  5. 用Django Rest Framework和AngularJS开始你的项目

    Reference: http://blog.csdn.net/seele52/article/details/14105445 译序:虽然本文号称是"hello world式的教程&quo ...

  6. 浅谈Django的Q查询以及AngularJS的Datatables分页插件

    使用Q查询,首先要导入Q模块: from django.db.models import Q 可以组合使用&,|操作符用于多个Q的对象,产生一个新的Q对象,Q对象也可以用~操作符放在前面表示否 ...

  7. Getting Started with Django Rest Framework and AngularJS

    转载自:http://blog.kevinastone.com/getting-started-with-django-rest-framework-and-angularjs.html A ReST ...

  8. Angularjs &dollar;http服务的两个request安全问题

    今天为了hybrid app和后端restful服务的安全认证问题,又翻了一下$http的文档,$http服务文档页面两个安全问题是json和XSRF,JSON那个比较好理解,就不补充什么了,说说XS ...

  9. 【转】Laravel&plus;Angularjs&plus;D3打造可视化数据&comma;RESTful&plus;Ajax

    http://897371388.iteye.com/blog/1975351 大致思路也就是下面,由于最近在学Laravel也在学Angularjs,加上之前做的项目用到了d3. 原来的方案如下: ...

随机推荐

  1. ENode框架使用场景简述

    ENode是一个.NET平台下,纯C#开发的,基于DDD,CQRS,ES,EDA,In-Memory架构风格的,可以帮助开发者开发高并发.高吞吐.可伸缩.可扩展的应用程序. 开源项目地址:https: ...

  2. 【类库】容器对象&lpar;List、DataTable、 DataView、Dictionary&rpar;

    首先申明一下,写此博文的目的是纪录一下,知识都是现成的,只是整理一下,为了让自己更容易看懂,比在其他地方更容易明白.因为它们太常用了,不忍心每次都去用那么长的时间查看MSDN,希望能在这里用理少的时间 ...

  3. PHP 后台定时循环刷新某个页面 屏蔽apache意外停止

    PHP 后台定时循环刷新某个页面 如果间隔时间过长的话  会出现apache自动停止的现象.出现的原因则是设置了 <IfModule mpm_winnt_module> ThreadsPe ...

  4. 【jqGrid for ASP&period;NET MVC Documentation】&period;学习笔记&period;3&period;本地化语言包

    1 引用本地化语言包 在 js/i18n 文件夹中,提供了大量预定义的语言包.它包括为所有字符串定义的,包括消息,标题,分页信息,搜索/添加/删除 的对话框 文本等. 在jQuery库文件后,在jqG ...

  5. android实现文本复制到剪切板功能&lpar;ClipboardManager&rpar;

    Android也有剪切板(ClipboardManager),可以复制一些有用的文本到剪贴板,以便用户可以粘贴的地方使用,下面是使用方法   注意:导包的时候 API 11之前: android.te ...

  6. iOS播放gif图方式

    转发:http://www.cnblogs.com/jerehedu/ 图片分为静态和动态两种,图片的格式有很多种,在开发中比较常见的是.png和.jpg的静态图片,但有的时候在App中需要播放动态图 ...

  7. 读阮一峰对《javascript语言精粹》的笔记,我有疑问。

    <javascript语言精粹>是一本很棒的书籍,其中作者在附录列出了12种他所认为的javascript语言中的糟粕. 我最近开始跟读前端前辈的博客,其中读到了阮一峰的<12种不宜 ...

  8. 开源Spring解决方案--lm&period;solution

    Github 项目地址: https://github.com/liumeng0403/lm.solution 一.说明 1.本项目未按java项目传统命名方式命名项目名,包名 如:org.xxxx. ...

  9. nodejs 动态创建二维码

    <!--弹出二维码--> <div class="qrcode"> <div> <p id="saoma">扫描 ...

  10. 使用4K分辨率&comma;然后放大DIP200&percnt;&comma;软件界面异常&period;

    简单:WFM主界面.AutoScaleMode  选中DIP,然后使用表格容器,容器分割,容器.就可以快速迁移旧程序. 复杂点:读取桌面分辨率,DIP放大....