Fazendo com que os padrões de URL do Django funcionem bem com $ routeProvider do Angular

Postado cruzado em meu blog: http://beshr.com/archives/django_urls_angular_route.html

Atualmente, estou escrevendo um projeto Django que depende muito do AngularJS. Não encontrei muitos tutoriais com dicas sobre como realizar essa tarefa, mas não tive nenhum problema até agora, pelo menos até querer que meus padrões de URL no Django funcionassem bem com as rotas do Angular.

O principal problema com essa tarefa, especificamente, é que tanto o Django quanto o Angular fornecem sua própria maneira de trabalhar com URLs. Você precisará satisfazer os padrões de URL / View do Django se estiver planejando ter qualquer lógica do lado do servidor controlada por suas views, mesmo que seja apenas para fornecer alguns dados de seu banco de dados. Mas você também pode querer aproveitar a grandeza das rotas do Angular e HTMLs parciais que são carregados instantaneamente, algo como HTML assíncrono e HTTP, mas com links permanentes reais e botão Voltar ativo.

** Observação: você pode querer dar uma olhada em django-pjax para obter recursos semelhantes apenas com jQuery. **

app.config(['$routeProvider',  function($routeProvider) {
$routeProvider

.when('/', {
templateUrl
: 'views/main.html',
controller
: 'MainCtrl'
})
.when('/about', {
templateUrl
: 'views/about.html',
})
.when('/help', {
templateUrl
: 'views/help.html',
})
.when('/post/:id', {
templateUrl
: 'views/postRouter.html',
controller
: 'PostCtrl'
})
.otherwise({
redirectTo
: '/'
});
}])

Antes de passar por cada uma dessas rotas individualmente, dê uma olhada no código que estou usando no URLs.py do django para os urlpatterns.

urlpatterns = patterns('',
url
(r'^$', 'myproject.views.home', name='home'),
url
(r'^views/main.html/$', 'myproject.views.main_view'),
url
(r'^views/post.html', 'myproject.views.post_view'),
url
(r'^views/(?P<page>[-w]+.html)/$', 'myproject.views.angular_views'),
url
(r'^(?P<path>.*)/$', 'myproject.views.angular_redirector'),
)

Como você pode notar, estou usando alguns truques para fazer isso acontecer.

  • O quarto padrão de URL que estou usando é o fallback para qualquer HTML parcial (modelo) para o qual o Angular está roteando esses links. Basicamente, dentro dos meus modelos angulares, tenho um bloco principal para uma visualização ng. O conteúdo deste bloco está sendo controlado pelo $ routeProvider, que carrega diferentes templates HTML (templateUrl) para satisfazer cada rota, que se parece com isto: http://127.0.0.1:800/#/http: //127.0 .0.1: 800 / # / abouthttp://127.0.0.1:800/#/helphttp://127.0.0.1:800/#/post/1

  • Os 2º e 3º padrões de URL também são modelos que o Angular está usando para satisfazer a 1ª e a 4ª rotas, mas cada um tem sua própria função de visualização porque cada um precisa de alguns dados do banco de dados e algum processamento de backend. A ideia do primeiro (views / main.html) por exemplo é carregar os posts mais recentes do banco de dados, descobrir algumas informações sobre o usuário logado, comentários, etc.

  • Mas as coisas são um pouco diferentes para o terceiro padrão de URL porque este deve carregar dados dinamicamente do banco de dados de acordo com a postagem que o usuário está carregando. Para compartilhar variáveis ​​entre as rotas do Angular e as visualizações do Django, agrupei os valores que preciso com a URL de solicitação da rota de postagem como variáveis ​​GET, dessa forma eu poderia carregá-las na visualização e extrair os dados da solicitação de acordo. O truque para fazer isso é rotear o url de “/ post /: id” para um html temporário (postRouter) que tem uma linha de código muito simples:

    <div ng-include src = “templateUrl”> </div>

O valor de templateUrl neste modelo será atribuído no controlador PostCtrl com algo assim:

app.controller('PostCtrl', ['$scope', '$routeParams', function($scope, $routeParams) {
$scope
.templateUrl = 'views/post.html?id='+$routeParams.id;
}]);

O que isto está essencialmente fazendo é carregar “views / post.html? Id = post id” e passando-o pelo Django nos bastidores, permitindo assim que a função view post view faça o que quiser com o conteúdo e passe para o template post.html atual renderizando toda a sua linguagem de template django e carregando o conteúdo de acordo, então passe-o novamente para o Angular para visualizá-lo no bloco ng-view atribuído.

Eu testei isso e funcionou exatamente do jeito que eu queria. Se você notou algo errado, ou se está fazendo de forma diferente, compartilhe nos comentários!

  • * Se você está curioso sobre o quinto padrão de url e a visualização angular_redirector estão fazendo, é apenas uma maneira muito básica de rotear solicitações que chegam para passar pelo Angular primeiro adicionando o # / antes do caminho do url. *