{"id":28067632,"url":"https://github.com/appliedsec/djangular","last_synced_at":"2025-05-12T16:58:40.807Z","repository":{"id":7027155,"uuid":"8300296","full_name":"appliedsec/djangular","owner":"appliedsec","description":"A reusable Django app that provides better integration and tools for Angular.js","archived":false,"fork":false,"pushed_at":"2020-01-21T12:25:31.000Z","size":2232,"stargazers_count":219,"open_issues_count":13,"forks_count":40,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-05-10T09:26:56.868Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/appliedsec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-19T21:50:50.000Z","updated_at":"2024-11-28T16:31:22.000Z","dependencies_parsed_at":"2022-09-07T15:51:00.300Z","dependency_job_id":null,"html_url":"https://github.com/appliedsec/djangular","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appliedsec%2Fdjangular","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appliedsec%2Fdjangular/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appliedsec%2Fdjangular/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/appliedsec%2Fdjangular/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/appliedsec","download_url":"https://codeload.github.com/appliedsec/djangular/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253784645,"owners_count":21963895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-12T16:58:40.032Z","updated_at":"2025-05-12T16:58:40.801Z","avatar_url":"https://github.com/appliedsec.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"djangular\n=========\n\nA reusable app that provides better app integration with AngularJS. Djangular\nallows you to create AngularJS content per app, instead of creating a single\nmassive AngularJS application inside of Django. This allows you to selectively\nuse apps per site, as well as create a consistent structure across all of your\nDjango apps.\n\nThis is intended to be a Django version of the angular-seed project\n(https://github.com/angular/angular-seed). The current mindset is to limit the\namount of changes introduced by Djangular.\n\n\nFeatures\n--------\n\n+ Allows namespacing AngularJS content per Django app.  This allows the\n  AngularJS apps and modules to be included (or not) based on Django's settings,\n  and enforces a consistent structure to your Django/AngularJS apps.\n+ Includes an AngularJS module that includes a subset of features similar to\n  what Django provides in its templates.\n+ Adds a patch to AngularJS's $resource module, to enable end of URL slashes\n  that Django requires.\n+ Improves security by enabling of CSRF protection and JSON Vulnerability\n  between Django and AngularJS.\n+ ~~Scripts to allow running JS Unit and E2E tests, similar to the Django test\n  command.~~ This was removed for the time being and will be (re-)included in a\n  future release.\n+ Does not dictate how you use AngularJS inside your Django app.\n\n\nRequirements\n------------\n\n+ Currently requires Python 2.7.\n+ Supports Django \u003e= 1.5, \u003c= 1.9\n+ Supports AngularJS 1.2+ (including 1.3.x).\n+ ~~Local installs of Node.js and Karma for testing.~~\n\n\nInstallation\n------------\n\n+ You may install directly from pypi:\n\n        pip install djangular\n\n+ Or download the source and install it in a terminal/console:\n\n        python setup.py install\n\n+ Or download the source and move the djangular directory inside your django\n  project as an app (this is the least recommended approach).\n\n+ Djangular needs to be placed as an app inside a Django project and added to\n  the INSTALLED_APPS setting.\n\n        INSTALLED_APPS = (\n            ...\n            'djangular',\n            ...\n        )\n\n+ You will need to obtain a version of AngularJS and place it in the `static`\n  folder of one of your Django apps.  Djangular no longer includes a version of\n  AngularJS, since it updates too frequently.\n\n\nIncluding AngularJS content in your Django Apps\n-----------------------------------------------\n\nThe most popular feature of Djangular, this will both include and namespace your\nAngularJS content inside your Django apps.  Each Django app has its own\n\"angular\" folder, with a layout matching the angular-seed project. As a result,\nthe URLs for these get grouped into the `STATIC_URL` structure of Django.\n\n+ The staticfiles contrib library will need to be included in the INSTALLED_APPS\n  setting.\n\n        INSTALLED_APPS = (\n            ...\n            'django.contrib.staticfiles',\n            'djangular',\n            ...\n        )\n\n+ The STATICFILES_FINDERS needs to be updated to include\n  `djangular.finders.NamespacedAngularAppDirectoriesFinder`.\n\n        STATICFILES_FINDERS = (\n            'django.contrib.staticfiles.finders.FileSystemFinder',\n            'django.contrib.staticfiles.finders.AppDirectoriesFinder',\n            'djangular.finders.NamespacedAngularAppDirectoriesFinder'\n        )\n\n+ Because of this new finder, the `findstatic` and `collectstatic` commands will\n  place the angular files in each app in an associated an `\u003capp_name\u003e/` folder.\n  You will not need to namespace each of your static directories with the name\n  of your Django application (unless you really want to).\n    * Example: If you have a Django app named `foo` and you are using the\n      default `STATIC_URL` in your settings, the main AngularJS module named\n      `foo` would be found at `foo/angular/app.js` on the file system and at\n      `static/foo/app.js` from the browser.\n    * This namespacing is done automatically.  This a `foo` app and a `bar` app\n      can both have an `app.js` inside their `angular` directories, and they\n      will not collide.\n    * Note: Because of these URLs, referring to AngularJS content in a separate\n      app should use a `../\u003cseparate_app\u003e/` URL. This will help significantly\n      during testing to make sure paths are correct.\n    * Note: It is recommended to namespace the AngularJS code the same name as\n      the Django app. The created JS files do this already.\n\n+ To create an app that is already setup with the djangular (or angular-seed)\n  structure, run `python manage.py startangularapp \u003capp_name\u003e` from the command\n  line. This will create the files and directory structures needed for you to\n  get started.\n\n\nIncluding some Django template-like features in your AngularJS templates\n------------------------------------------------------------------------\n\nOne of the challenges in using AngularJS inside of Django is that you may not\nhave access to some needed variables that are always included in Django\ntemplates.  Djangular includes an AngularJS module to help with that.\n\n+ To use the AngularJS module that Djangular provides you, you'll need to add\n  the djangular app to your projects URLs.\n\n        urlpatterns = patterns('',\n            ...\n            url(r'^djangular/', include('djangular.urls')),\n            ...\n        )\n\n+ Alternatively, you may specify the DjangularModuleTemplateView specifically,\n  and customize the url.\n\n        from djangular.views import DjangularModuleTemplateView\n        ...\n\n        urlpatterns = patterns('',\n            ...\n            url(r'\u003ccustom_path\u003e/djangular.js',\n                DjangularModuleTemplateView.as_view()),\n            ...\n        )\n\nThis will add a `djangular` AngularJS module to your front end code.  This\nmodule includes a `DjangoProperties` constant that includes whether the current\nuser is authenticated, the username, groups and roles of the current user and\nthe static and media urls from Django settings.  It also includes a `django`\nfilter, which does some basic substitution based on the properties constant.\n\n\nEnforcing the end slashes of your AngularJS Resources\n-----------------------------------------------------\n\n$resource is a convenient way to create REST-like services in AngularJS.\nHowever, there currently\n[is a bug](https://github.com/angular/angular.js/issues/992) in $resource that\nwill strip the ending slash, which means that $resource is unusable unless\n`settings.APPEND_SLASHES` is set to `FALSE`.\n\nDjangular used to patch this automatically, but it now includes a separate file\n(`djangular/static/js/resource_patch.js`) to handle this issue.  Simply include\nthat javascript file in your page after you have loaded `angular-resource.js`\nand ending slashes will be preserved in $resource.\n\n\nEnabling CSRF protection in AngularJS Templates\n-----------------------------------------------\n\nDjangular includes a JSON Vulnerability middleware that AngularJS knows how to\nprocess. To include this protection, add\n`djangular.middleware.AngularJsonVulnerabilityMiddleware` to the\n`MIDDLEWARE_CLASSES` setting. This only affects JSON requests (based on\nContent-Type), so this can be located fairly low in the middleware stack.\n\n        MIDDLEWARE_CLASSES = (\n            ...\n            'djangular.middleware.AngularJsonVulnerabilityMiddleware'\n        )\n\nOnce you have enabled CSRF protection in Django by adding the middleware\n`django.middleware.csrf.CsrfViewMiddleware` to the `MIDDLEWARE_CLASSES` setting,\nyou may use the same protection in AngularJS templates in addition to Django\ntemplate.  There are two different ways to enable this protection via djangular:\n\n+ Make your main app dependent on the `djangular` module and use the included\n  `csrf-token` directive (that wraps the Django `csrf_token` template tag)\n  inside the appropriate `form` tags in your HTML.\n\n        // Inside your JavaScript\n        angular.module('myApp', ['djangular', ...]);\n        ...\n        \u003c!-- In your AngularJS Template --\u003e\n        \u003cdiv ng-app=\"my-app\"\u003e\n            ...\n            \u003cform ...\u003e\n                \u003ccsrf-token\u003e\u003c/csrf-token\u003e\n            \u003c/form\u003e\n        \u003c/div\u003e\n\n+ Make your main app dependent on the `djangular.csrf`, which will add the\n  appropriate CSRF Token Header in all POSTs, PUTs and DELETEs.  Note that this\n  way is vulnerable to cross-site scripting if you make a post to a domain\n  outside your control.\n\n        angular.module('myApp', ['djangular.csrf', ...]);\n\nIf you allow a user to login (or logout) and don't redirect or reload the page,\nthe tags and cookies provided by both methods above will be stale.  The second\noption (using the `djangular.csrf` module) provides a `UpdateCSRFToken` function\nthat can be invoked with the new CSRF Token value.\n\n\nUsing Djangular in your Django Project\n--------------------------------------\n\nThis section describes some best practices in using Djangular. Please note that\nthese are guidelines and recommendations, but not the only way to use this\nproject.\n\n#### AngularJS as purely static content ####\n\nThe first way to use djangular is to have all of your static content live inside\nan angular app. This is perhaps the \"most correct\" way from an AngularJS\nstandpoint and perhaps the \"least correct\" way from a traditional Django\nperspective.\n\nIn doing this, you are only (or almost only) serving content from your static\ndomain and your Django development becomes strictly back-end focused for REST\nand/or service calls. Few to none of your Django views will produce HTML. You\ncan provide a redirect from a Django view to your static pages (if you like),\nalthough this can seem strange when your static content is served from a\ncompletely different domain. You may need to configure your web servers to\nallow remote Ajax calls from your static domain.\n\nThis approach allows you to use AngularJS with any number of back-ends, as\n(again) your Django app becomes an API for your AngularJS code to call. This\napproach can be very different from how your application is currently\narchitected.\n\nFrom our experience, if you decide to do this, we would recommend using local,\nrelative URLs to navigate between the apps instead of specifying the full URL.\nHowever, there are times when you will need to specify the full URL.\n\nThere is an AngularJS module called `djangular` that is rendered via the Django\ntemplating engine to obtain common template variables like the `STATIC_URL`,\n`MEDIA_URL`, the User object, etc.  This app includes a service called\n`DjangoProperties`, which will enable you to get access to those variables, and\na `django` filter, which follows the standard AngularJS filtering rules. The URL\nfor this JavaScript is `/djangular/app.js` (note that is not static).\n\nThe following is a sample route config that uses the aforementioned djangular\nangular app. Because AngularJS has not set up the $filter directive during the\nroute configuration, the DjangoProperties constant is the only way to obtain the\nSTATIC_URL. Using 'sample' as the name of the Django/AngularJS app:\n\n```javascript\nangular.module('sample', [\n    'djangular', 'sample.filters', 'sample.services', 'sample.directives',\n    'sample.controllers'\n    ]).config([\n        '$routeProvider','DjangoProperties',\n        function($routeProvider, DjangoProperties) {\n            $routeProvider.when('/view1', {\n                templateUrl: DjangoProperties.STATIC_URL +\n                    'sample/view1/view1.html', controller: 'View1Ctrl'});\n            $routeProvider.when('/view2', {\n                templateUrl: DjangoProperties.STATIC_URL +\n                    'sample/view2/view2.html', controller: 'View2Ctrl'});\n            $routeProvider.otherwise({redirectTo: '/view1'});\n        }\n    ]);\n```\n\n#### Django Templates as AngularJS Templates ####\n\nAnother way to integrate is to use your Django templates as your AngularJS\ntemplates. To do this, we highly recommend using Django 1.5 and heavy use of\nthe `{% verbatim %}` tag, since the Django and AngularJS templating syntaxes are\nidentical.\n\nThe big advantage of this is that it allows you to use all of the existing\ntemplate tags and ways of thinking that you are accustomed to using. If you are\nintegrating AngularJS into an existing Django project, this will seem the most\nappealing.\n\nThe downsides to this method are the following:\n+ The AngularJS developers recommend not doing this, because it is very easy\n  to get confused about which part of the template is being rendered on the\n  server side and which is being rendered on the client side. Almost every\n  developer on our team has tripped on this once or twice.\n+ The vast majority of HTML that your app is producing is the same on every\n  load... and should be static. However, without some cache configuration, the\n  server will have to render the content on every single request, resulting in\n  poorer performance.\n\n#### Using Django Templates to render the skeleton of the app ####\n\nWhat our team currently does is use a Django Template to render the skeleton of\nevery page, but the rest of the page (the partials, CSS and JS) are all included\nin the AngularJS app. This way, none of the CSS/JS dependencies are duplicated\nin multiple places.\n\nWhen our app renders the content, we pass in two variables to the RequestContext\n(and thus, to the template). The `app_name`, which is the name of the app, and\n`app_dependencies`, which is a list of app names whom the AngularJS app is\ndependent on. We make heavy use of Django Rest Framework\n(http://django-rest-framework.org/) to produce our views/REST Services and\nDjango Pipeline (https://github.com/cyberdelia/django-pipeline) to do our app\npackaging and JS/CSS Compression.\n\nThe template (more or less) looks like the following:\n```html\n{% load compressed %}  \u003c!-- We use django-pipeline to do our packaging --\u003e\n\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003cmeta charset=\"utf-8\"\u003e\n    \u003ctitle\u003eApp Title\u003c/title\u003e\n\t\u003clink rel=\"shortcut icon\" href=\"{{ STATIC_URL }}images/app.ico\" /\u003e\n\n    \u003c!--CSS imports--\u003e\n    {% for dependency in app_dependencies %}\n        {% compressed_css dependency %}\n    {% endfor %}\n    {% compressed_css app_name %}\n\n    \u003c!--AngularJS library imports--\u003e\n    \u003cscript src=\"{{ STATIC_URL }}angular/angular-min.js\"\u003e\u003c/script\u003e\n\n    \u003c!--AngularJS app imports--\u003e\n    \u003cscript src=\"/djangular/app.js\"\u003e\u003c/script\u003e  \u003c!-- The djangular app. --\u003e\n    {% for dependency in app_dependencies %}\n        {% compressed_js dependency %}\n    {% endfor %}\n    {% compressed_js app_name %}\n\n\u003c/head\u003e\n\u003cbody ng-app=\"{{app_name}}\"\u003e\n    \u003cdiv class=\"app\" ng-view\u003e\n    \u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappliedsec%2Fdjangular","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fappliedsec%2Fdjangular","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fappliedsec%2Fdjangular/lists"}