【问题标题】:django-rest pagination with angularjs使用 angularjs 进行 django-rest 分页
【发布时间】:2014-08-28 00:16:05
【问题描述】:

我有一个 angularjs 应用程序可以很好地与 django-rest 配合使用,但通过引入分页遇到了问题。我有一个休息服务和控制器,如下所示

// restservices.js
// API call for all images in an event
services.factory('ImageEvent', function ($resource) {
    return $resource(rest_api + '/rest/image/?event_id=:eventId&format=json', {}, {
        query: { method:'GET', params:{eventId:''}, isArray:true}
    })
}); 

// controllers.js
// all Images in an event
.controller('ImageEventCtrl', ['$scope', '$stateParams', 'ImageEvent', function($scope, $stateParams, ImageEvent) {
  $scope.images = ImageEvent.query({eventId: $stateParams.eventId}, function(images) {
  });
}])

这将返回以下 json

[
    {
        "id": 13,
        "title": "01-IMG_4953.JPG",
    },
    {
        "id": 14,
        "title": "02-IMG_4975.JPG",
    },
    {
        "id": 15,
        "title": "03-IMG_4997.JPG",
    }
]

但是,如果我打开 django-rest 分页,它会返回以下 json:

{

    "count": 3,
    "next": "/rest/image/?event_id=1&page=2",
    "previous": null,
    "results": 
    [

        {
            "id": 13,
            "title": "01-IMG_4953.JPG",
        },
        {
            "id": 14,
            "title": "02-IMG_4975.JPG",
        }
    ]

}

此更改导致以下控制台错误,并且一切都无法正常工作:

错误:[$resource:badcfg] 资源配置错误。预期的响应包含一个数组但得到一个对象

将 restservice 更改为 isArray:false 没有任何区别。是否可以重写我的控制器以应对此问题,并且在完美的情况下还可以公开计数、下一个和上一个链接?

谢谢

【问题讨论】:

    标签: json django angularjs rest pagination


    【解决方案1】:

    Angular-ui 有一个分页指令,我以前在 Django Rest Framework 中使用过。

    http://angular-ui.github.io/bootstrap/#/pagination

    要一次仅加载 X 数量的项目,我执行了以下操作。请注意,我正在使用分页以 Angular 重新创建 django 管理功能。

    if request.GET.get('page'):   
        # Get the page number                     
        page = request.GET.get('page')
    
        # How many items per page to display                 
        per_page = data['admin_attrs']['list_per_page']        
    
    
        begin = (int(page) - 1) * per_page                     
        end = begin + per_page                                 
    
        objects = MODEL.objects.all()[begin:end]               
    
    # Serializer for your corresponding itmes. This will grab the particular modelserializer                                                           
    serializer = serializer_classes[MODEL._meta.object_name](  
        objects, fields=admin_attrs['list_display']            
    )                                                          
    
    
    data['objects'] = serializer.data                          
    return Response(data)         
    

    我的 Angular 代码用于跟踪页面并允许返回按钮功能并更新 URL:

    modelDetails Factory 通过分页生成具有正确页码的 url

    app.factory('modelDetails', function($http, $q){                          
        data = {content: null}                                                                                                         
        var dataFactory = {}                                                  
        dataFactory.getObjects = function (app, model, page){                 
            var deferred = $q.defer()                                         
            $http.get('api/admin/' + app + '/' + model + '/?page=' + page)    
                .success(function(result) {                                   
                    deferred.resolve(result);                                 
                });                                                           
            return  deferred.promise                                          
        };                                                                    
    
        return dataFactory                                                    
    });    
    
    
    
    $scope.loadObjects = function () {                                                         
        modelDetails.getObjects(app, model, $scope.currentPage)                                
        .then(function (data){                                                                 
            $scope.headers = data.headers;                                                     
            $scope.admin_attrs = data.admin_attrs;                                             
    
            blank =  new Array()                                                               
            list_display = data.admin_attrs.list_display                                       
    
            $scope.objects = convertObjects(data.objects, list_display)                        
            $scope.numPerPage = data.admin_attrs.list_per_page                                 
            $scope.currentPage = $stateParams.p                                                
            $scope.maxSize = 20;                                                               
            $scope.bigTotalItems = data.object_count;                                          
            $scope.numPages = Math.ceil(data.object_count /                $scope.admin_attrs.list_per_page); 
    
        })                                                                                     
        .then( function (data) {                                                               
    
            $scope.$watch('currentPage + numPerPage', function(oldVal, newVal) {               
                var begin = (($scope.currentPage - 1) * $scope.numPerPage)                     
                , end = begin + $scope.numPerPage;                                             
    
                if(oldVal != newVal){                                                          
                    $location.search('p', $scope.currentPage)                                  
                }                                                                              
    
                $rootScope.$on('$locationChangeSuccess', function(event) {                     
                    $scope.currentPage = $location.search().p                                  
                        modelDetails.getObjects(app, model, $scope.currentPage)                
                            .then( function (data) {  
                                // convertObjects just reorders my data in a way I want                                         
                                $scope.objects = convertObjects(data.objects, list_display)    
                            });                                                                
                });                                                                            
            });                                                                                
         });                                                                                   
    }                 
    

    【讨论】:

    • 谢谢,我去看看。关于这是否会加载整个结果集然后 angular-ui 对其进行分页的任何看法?我的结果集太大了,无法全部加载然后对其进行切片。
    • 我已经更新了我的答案。您必须根据自己的需要进行修改,但到目前为止它对我有用。我并不是说这是完美的,因为我自己仍在努力。
    • 谢谢,我没有完全按照您的路线走,而是使用您的代码作为基础,在我的 REST api 中提供分页。真的好用
    • 你有回购或其他地方我可以查看在 Angular 中使用 django admin 的代码吗?现在要使用 django 管理员,我必须关闭 html5 模式。
    • @shnek 前段时间我创建了一个 repo,试图完全复制 django admin 的角度,但现在已经有一年多了。随意使用,因为它远非稳定。肯定没做好。我在它中间停了下来:github.com/austinhuminski/angular-django-admin
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 2021-07-12
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多