发布于2019-08-22 15:52 阅读(1788) 评论(0) 点赞(27) 收藏(4)
好吧,我承认自己很懒,时间又不够用。
翻译的几个文章都是虎头蛇尾,但我保证这次肯定不太监。
关键的单词不翻译,实在觉得翻译成汉语很别扭,括号里是参考翻译。
有问题和建议尽管提出来,我会改进完善。
原文: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:
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
我记得TastyPies官方文档建议在你的应用中用api.py来命名此文件。这也是我的做法,尽管它不是强制的。你可以随意命名,但是按照约定命名文件可以保证一致性。
JobResource 的一些设置已经超出了本文章的范围。但我乐于解释JobResource是继承自ModelResource的。 结合Tastypie与Django ORM两者使用。扩展它意味着你已经能够能深入API的基本实现了。
TastyPie 也能处理非ORM数据。通过直接扩展Resource,你也能够得到TastyPie提供的所有好处。 No SQL数据库描述如下(点我)。
现在你已经创建了模型和与之交互的方式。接下来,你需要一个把resource连接到实际URL的步骤,如此,AngularJS才能发挥它的作用。 简单的举例说明如何在Django URLConf里建立这样的连接。:
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)), )
在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和它的社区。
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'
为了简便,你需要创建如下三个模板。
templates jobs/index.html jobs/new.html base.html
这说明你有一个叫job的app并且已经安装了。你的base模板会像下面一样:
/jobs/base.html
<!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>
Django-Angular已经提供了很多很好的模板标签,这些标签包含了必要的javascript。我建议使用分布式目录网络(CDN)来加载必要的文件。如此做,你会得到明显的地理上的和宽带资源上的好处。
你需要创建一个page模板。index.html会作为主页,它会接收请求。
/jobs/index.html
{% 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 %}
/javascript/app.js
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
模板和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返回时,你可以添加一个默认的行为。
$urlRouterProvider.otherwise("/");
$stateProvider
.state('index', {
url: "/",
templateUrl: "static/html/somepage.html",
controller: "SomeController"
})
如果你还不熟悉这些,看完此文我建议你读 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
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
/jobs/urls.py
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'), )
用你的浏览器访问 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
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) },
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.
作者:滴水
链接:https://www.pythonheidong.com/blog/article/52607/277193bceb1a6150fd25/
来源:python黑洞网
任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任
昵称:
评论内容:(最多支持255个字符)
---无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事,而不是让内心的烦躁、焦虑,坏掉你本来就不多的热情和定力
Copyright © 2018-2021 python黑洞网 All Rights Reserved 版权所有,并保留所有权利。 京ICP备18063182号-1
投诉与举报,广告合作请联系vgs_info@163.com或QQ3083709327
免责声明:网站文章均由用户上传,仅供读者学习交流使用,禁止用做商业用途。若文章涉及色情,反动,侵权等违法信息,请向我们举报,一经核实我们会立即删除!